mirror of
git://sourceware.org/git/lvm2.git
synced 2025-10-03 01:44:19 +03:00
Compare commits
1 Commits
dev-dct-ca
...
dev-dct-ca
Author | SHA1 | Date | |
---|---|---|---|
|
62b606e82a |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -30,19 +30,14 @@ make.tmpl
|
||||
/config.log
|
||||
/config.status
|
||||
/configure.scan
|
||||
/cscope.*
|
||||
/cscope.out
|
||||
/html/
|
||||
/python/
|
||||
/reports/
|
||||
/tags
|
||||
/tmp/
|
||||
|
||||
coverity/coverity_model.xml
|
||||
|
||||
# gcov files:
|
||||
*.gcda
|
||||
*.gcno
|
||||
|
||||
tools/man-generator
|
||||
tools/man-generator.c
|
||||
|
||||
|
45
Makefile.in
45
Makefile.in
@@ -18,7 +18,7 @@ top_builddir = @top_builddir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
|
||||
SUBDIRS = libdm conf daemons include lib libdaemon man scripts tools
|
||||
SUBDIRS = conf daemons include lib libdaemon libdm man scripts tools
|
||||
|
||||
ifeq ("@UDEV_RULES@", "yes")
|
||||
SUBDIRS += udev
|
||||
@@ -47,6 +47,8 @@ include $(top_srcdir)/base/Makefile
|
||||
include $(top_srcdir)/device_mapper/Makefile
|
||||
include $(top_srcdir)/test/unit/Makefile
|
||||
|
||||
libdm: include
|
||||
libdaemon: include
|
||||
lib: libdaemon $(BASE_TARGET) $(DEVICE_MAPPER_TARGET)
|
||||
daemons: lib libdaemon tools
|
||||
scripts: lib
|
||||
@@ -54,13 +56,16 @@ tools: lib libdaemon
|
||||
po: tools daemons
|
||||
man: tools
|
||||
all_man: tools
|
||||
scripts: libdm
|
||||
test: tools daemons
|
||||
unit-test run-unit-test: test
|
||||
|
||||
lib.device-mapper: include.device-mapper
|
||||
libdm.device-mapper: include.device-mapper
|
||||
daemons.device-mapper: libdm.device-mapper
|
||||
tools.device-mapper: libdm.device-mapper
|
||||
scripts.device-mapper: include.device-mapper
|
||||
device-mapper: tools.device-mapper daemons.device-mapper man.device-mapper
|
||||
device_mapper: device-mapper
|
||||
|
||||
ifeq ("@INTL@", "yes")
|
||||
lib.pofile: include.pofile
|
||||
@@ -76,10 +81,9 @@ daemons.cflow: tools.cflow
|
||||
cflow: include.cflow
|
||||
endif
|
||||
|
||||
CSCOPE_DIRS = base daemons device_mapper include lib libdaemon scripts tools libdm test
|
||||
ifneq ("@CSCOPE_CMD@", "")
|
||||
cscope.out:
|
||||
@CSCOPE_CMD@ -b -R $(patsubst %,-s%,$(addprefix $(srcdir)/,$(CSCOPE_DIRS)))
|
||||
@CSCOPE_CMD@ -b -R -s$(top_srcdir)
|
||||
all: cscope.out
|
||||
endif
|
||||
DISTCLEAN_TARGETS += cscope.out
|
||||
@@ -112,11 +116,11 @@ rpm: dist
|
||||
$(LN_S) -f $(abs_top_srcdir)/spec/packages.inc $(rpmbuilddir)/SOURCES
|
||||
DM_VER=$$(cut -d- -f1 $(top_srcdir)/VERSION_DM);\
|
||||
GIT_VER=$$(cd $(top_srcdir); git describe | cut -d- --output-delimiter=. -f2,3 || echo 0);\
|
||||
$(SED) -e "s,\(device_mapper_version\) [0-9.]*$$,\1 $$DM_VER," \
|
||||
sed -e "s,\(device_mapper_version\) [0-9.]*$$,\1 $$DM_VER," \
|
||||
-e "s,^\(Version:[^0-9%]*\)[0-9.]*$$,\1 $(LVM_VER)," \
|
||||
-e "s,^\(Release:[^0-9%]*\)[0-9.]\+,\1 $$GIT_VER," \
|
||||
$(top_srcdir)/spec/source.inc >$(rpmbuilddir)/SOURCES/source.inc
|
||||
V=$(V) rpmbuild -v --define "_topdir $(rpmbuilddir)" -ba $(top_srcdir)/spec/lvm2.spec
|
||||
rpmbuild -v --define "_topdir $(rpmbuilddir)" -ba $(top_srcdir)/spec/lvm2.spec
|
||||
|
||||
generate: conf.generate man.generate
|
||||
$(MAKE) -C conf generate
|
||||
@@ -150,31 +154,6 @@ install_all_man:
|
||||
install_tmpfiles_configuration:
|
||||
$(MAKE) -C scripts install_tmpfiles_configuration
|
||||
|
||||
help:
|
||||
@echo -e "\nAvailable targets:"
|
||||
@echo " all Default target."
|
||||
@echo " all_man Build all man pages with generators."
|
||||
@echo " clean Remove all compile files."
|
||||
@echo " device-mapper Device mapper part of lvm2."
|
||||
@echo " dist Generate distributable file."
|
||||
@echo " distclean Remove all build files."
|
||||
@echo " generate Generate man pages for sources."
|
||||
@echo " help Display callable targets."
|
||||
@echo " install Install all files."
|
||||
@echo " install_all_man Install all man pages."
|
||||
@echo " install_cluster Install cmirrord."
|
||||
@echo " install_device-mapper Install device mapper files."
|
||||
@echo " install_initscripts Install initialization scripts."
|
||||
@echo " install_lvm2 Install lvm2 files."
|
||||
@echo " install_systemd_units Install systemd units."
|
||||
@echo " lcov Generate lcov output."
|
||||
@echo " lcov-dated Generate lcov with timedate suffix."
|
||||
@echo " lcov-reset Reset lcov counters"
|
||||
@echo " man Build man pages."
|
||||
@echo " rpm Build rpm."
|
||||
@echo " run-unit-test Run unit tests."
|
||||
@echo " tags Generate c/etags."
|
||||
|
||||
ifneq ("$(LCOV)", "")
|
||||
.PHONY: lcov-reset lcov lcov-dated
|
||||
|
||||
@@ -204,8 +183,8 @@ endif
|
||||
ifneq ($(shell which ctags 2>/dev/null),)
|
||||
.PHONY: tags
|
||||
tags:
|
||||
test -z "$(shell find $(addprefix $(top_srcdir)/,$(CSCOPE_DIRS)) -type f -name '*.[ch]' -newer tags 2>/dev/null | head -1)" || $(RM) tags
|
||||
test -f tags || find $(addprefix $(top_srcdir)/,$(CSCOPE_DIRS)) -maxdepth 5 -type f -name '*.[ch]' -exec ctags -a '{}' +
|
||||
test -z "$(shell find $(top_srcdir) -type f -name '*.[ch]' -newer tags 2>/dev/null | head -1)" || $(RM) tags
|
||||
test -f tags || find $(top_srcdir) -maxdepth 5 -type f -name '*.[ch]' -exec ctags -a '{}' +
|
||||
|
||||
CLEAN_TARGETS += tags
|
||||
endif
|
||||
|
11
README
11
README
@@ -1,6 +1,7 @@
|
||||
This tree contains the LVM2 and device-mapper tools and libraries.
|
||||
|
||||
This is development branch, for stable 2.02 release see stable-2.02 branch.
|
||||
This is development branch, for stable 2.02 release see 2018-06-01-stable
|
||||
branch.
|
||||
|
||||
For more information about LVM2 read the changelog in the WHATS_NEW file.
|
||||
Installation instructions are in INSTALL.
|
||||
@@ -9,6 +10,7 @@ There is no warranty - see COPYING and COPYING.LIB.
|
||||
|
||||
Tarballs are available from:
|
||||
ftp://sourceware.org/pub/lvm2/
|
||||
ftp://sources.redhat.com/pub/lvm2/
|
||||
https://github.com/lvmteam/lvm2/releases
|
||||
|
||||
The source code is stored in git:
|
||||
@@ -43,9 +45,6 @@ Report upstream bugs at:
|
||||
or open issues at:
|
||||
https://github.com/lvmteam/lvm2/issues
|
||||
|
||||
The source code repository used until 7th June 2012 is accessible using CVS:
|
||||
The source code repository used until 7th June 2012 is accessible here:
|
||||
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/?cvsroot=lvm2.
|
||||
|
||||
cvs -d :pserver:cvs@sourceware.org:/cvs/lvm2 login cvs
|
||||
cvs -d :pserver:cvs@sourceware.org:/cvs/lvm2 checkout LVM2
|
||||
|
||||
The password is cvs.
|
||||
|
@@ -1 +1 @@
|
||||
1.02.177-git (2021-01-08)
|
||||
1.02.167-git (2019-10-23)
|
||||
|
136
WHATS_NEW
136
WHATS_NEW
@@ -1,139 +1,7 @@
|
||||
Version 2.03.12 -
|
||||
Version 2.03.07 -
|
||||
===================================
|
||||
Better hyphenation usage in man pages.
|
||||
Replace use of deprecated security_context_t with char*.
|
||||
Configure supports AIO_LIBS and AIO_CFLAGS.
|
||||
Improve build process for static builds.
|
||||
Improve signal handling with lvmpolld.
|
||||
Signal handler can interrupt command also for SIGTERM.
|
||||
Lvreduce --yes support.
|
||||
Add configure option --with/out-symvers for non-glibc builds.
|
||||
Report error when the filesystem is missing on fsadm resized volume.
|
||||
Handle better blockdev with --getsize64 support for fsadm.
|
||||
Do not include editline/history.h when using editline library.
|
||||
Support error and zero segtype for thin-pool data for testing.
|
||||
Support mixed extension for striped, error and zero segtypes.
|
||||
Support resize also for stacked virtual volumes.
|
||||
Skip dm-zero devices just like with dm-error target.
|
||||
Reduce ioctl() calls when checking target status.
|
||||
Merge polling does not fail, when LV is found to be already merged.
|
||||
Poll volumes with at least 100ms delays.
|
||||
Do not flush dm cache when cached LV is going to be removed.
|
||||
Support interruption while waiting on device close before deactivation.
|
||||
Flush thin-pool messages before removing more thin volumes.
|
||||
Improve hash function with less collisions and make it faster.
|
||||
Reduce ioctl count when deactivating volumes.
|
||||
Reduce number of metadata parsing.
|
||||
Enhance performance of lvremove and vgremove commands.
|
||||
Support interruption when taking archive and backup.
|
||||
Accelerate large lvremoves.
|
||||
Speedup search for cached device nodes.
|
||||
Speedup command initialization.
|
||||
Add devices file feature, off by default for now.
|
||||
Support extension of writecached volumes.
|
||||
Fix problem with unbound variable usage within fsadm.
|
||||
Check for presence of VDO target before starting any conversion.
|
||||
Support metatadata profiles with volume VDO pool conversions.
|
||||
Support -Zn for conversion of already formated VDO pools.
|
||||
Avoid removing LVs on error path of lvconvert during creation volumes.
|
||||
Fix crashing lvdisplay when thin volume was waiting for merge.
|
||||
Support option --errorwhenfull when converting volume to thin-pool.
|
||||
Improve thin-performance profile support conversion to thin-pool.
|
||||
Add workaround to avoid read of internal 'converted' devices.
|
||||
Prohibit merging snapshot into the read-only thick snapshot origin.
|
||||
Restore support for flipping rw/r permissions for thin snapshot origin.
|
||||
Support resize of cached volumes.
|
||||
Disable autoactivation with global/event_activation=0.
|
||||
Check if lvcreate passes read_only_volume_list with tags and skips zeroing.
|
||||
Allocation prints better error when metadata cannot fit on a single PV.
|
||||
Pvmove can better resolve full thin-pool tree move.
|
||||
Limit pool metadata spare to 16GiB.
|
||||
Improves convertsion and allocation of pool metadata.
|
||||
Support thin pool metadata 15.88GiB, adds 64MiB, thin_pool_crop_metadata=0.
|
||||
Enhance lvdisplay to report raid availiable/partial.
|
||||
Support online rename of VDO pools.
|
||||
Imporove removal of pmspare when last pool is removed.
|
||||
Fix problem with wiping of converted LVs.
|
||||
Fix memleak in scanning (2.03.11).
|
||||
Fix corner case allocation for thin-pools.
|
||||
|
||||
Version 2.03.11 - 08th January 2021
|
||||
===================================
|
||||
Fix pvck handling MDA at offset different from 4096.
|
||||
Partial or degraded activation of writecache is not allowed.
|
||||
Enhance error handling for fsadm and handle correct fsck result.
|
||||
Dmeventd lvm plugin ignores higher reserved_stack lvm.conf values.
|
||||
Support using BLKZEROOUT for clearing devices.
|
||||
Support interruption when wipping LVs.
|
||||
Support interruption for bcache waiting.
|
||||
Fix bcache when device has too many failing writes.
|
||||
Fix bcache waiting for IO completion with failing disks.
|
||||
Configure use own python path name order to prefer using python3.
|
||||
Add configure --enable-editline support as an alternative to readline.
|
||||
Enhance reporting and error handling when creating thin volumes.
|
||||
Enable vgsplit for VDO volumes.
|
||||
Lvextend of vdo pool volumes ensure at least 1 new VDO slab is added.
|
||||
Use revert_lv() on reload error path after vg_revert().
|
||||
Configure --with-integrity enabled.
|
||||
Restore lost signal blocking while VG lock is held.
|
||||
Improve estimation of needed extents when creating thin-pool.
|
||||
Use extra 1% when resizing thin-pool metadata LV with --use-policy.
|
||||
Enhance --use-policy percentage rounding.
|
||||
Configure --with-vdo and --with-writecache as internal segments.
|
||||
Improving VDO man page examples.
|
||||
Allow pvmove of writecache origin.
|
||||
Report integrity fields.
|
||||
Integrity volumes defaults to journal mode.
|
||||
Switch code base to use flexible array syntax.
|
||||
Fix 64bit math when calculation cachevol size.
|
||||
Preserve uint32_t for seqno handling.
|
||||
Switch from mmap to plain read when loading regular files.
|
||||
Update lvmvdo man page and better explain DISCARD usage.
|
||||
|
||||
Version 2.03.10 - 09th August 2020
|
||||
==================================
|
||||
Add writecache and integrity support to lvmdbusd.
|
||||
Generate unique cachevol name when default required from lvcreate.
|
||||
Converting RAID1 volume to one with same number of legs now succeeds with a
|
||||
warning.
|
||||
Fix conversion to raid from striped lagging type.
|
||||
Fix conversion to 'mirrored' mirror log with larger regionsize.
|
||||
Zero pool metadata on allocation (disable with allocation/zero_metadata=0).
|
||||
Failure in zeroing or wiping will fail command (bypass with -Zn, -Wn).
|
||||
Add lvcreate of new cache or writecache lv with single command.
|
||||
Fix running out of free buffers for async writing for larger writes.
|
||||
Add integrity with raid capability.
|
||||
Fix support for lvconvert --repair used by foreign apps (i.e. Docker).
|
||||
|
||||
Version 2.03.09 - 26th March 2020
|
||||
=================================
|
||||
Fix formating of vdopool (vdo_slab_size_mb was smaller by 2 bits).
|
||||
Fix showing of a dm kernel error when uncaching a volume with cachevol.
|
||||
|
||||
Version 2.03.08 - 11th February 2020
|
||||
====================================
|
||||
Prevent problematic snapshots of writecache volumes.
|
||||
Add error handling for failing allocation in _reserve_area().
|
||||
Fix memleak in syncing of internal cache.
|
||||
Fix pvck dump_current_text memleak.
|
||||
Fix lvmlockd result code on error path for _query_lock_lv().
|
||||
Update pvck man page and help output.
|
||||
Reject invalid writecache high/low_watermark setting.
|
||||
Report writecache status.
|
||||
Accept more output lines from vdo_format.
|
||||
Prohibit reshaping of stacked raid LVs.
|
||||
Avoid running cache input arg validation when creating vdo pool.
|
||||
Prevent raid reshaping of stacked volumes.
|
||||
Added VDO lvmdbusd methods for enable/disable compression & dedupe.
|
||||
Added VDO lvmdbusd method for converting LV to VDO pool.
|
||||
|
||||
Version 2.03.07 - 30th November 2019
|
||||
====================================
|
||||
Subcommand in vgck for repairing headers and metadata.
|
||||
Ensure minimum required region size on striped RaidLV creation.
|
||||
Fix resize of thin-pool with data and metadata of different segtype.
|
||||
Improve mirror type leg splitting.
|
||||
Improve error path handling in daemons on shutdown.
|
||||
Fix activation order when removing merged snapshot.
|
||||
Experimental VDO support for lvmdbusd.
|
||||
|
||||
@@ -1775,7 +1643,7 @@ Version 2.02.105 - 20th January 2014
|
||||
Allow lvmetad to reuse stale socket.
|
||||
Only unlink lvmetad socket on error if created by the same process.
|
||||
Append missing newline to lvmetad missing socket path error message.
|
||||
Check for non-zero alignment in _text_pv_add_metadata_area() to not div by 0.
|
||||
Check for non-zero aligment in _text_pv_add_metadata_area() to not div by 0.
|
||||
Add allocation/use_blkid_wiping to lvm.conf to enable blkid wiping.
|
||||
Enable blkid_wiping by default if the blkid library is present.
|
||||
Add configure --disable-blkid_wiping to disable libblkid signature detection.
|
||||
|
27
WHATS_NEW_DM
27
WHATS_NEW_DM
@@ -1,28 +1,5 @@
|
||||
Version 1.02.177 -
|
||||
Version 1.02.167 -
|
||||
====================================
|
||||
Configure proceeds without libaio to allow build of device-mapper only.
|
||||
Fix symbol versioning build with -O2 -flto.
|
||||
Add dm_tree_node_add_thin_pool_target_v1 with crop_metadata support.
|
||||
|
||||
Version 1.02.175 - 08th January 2021
|
||||
====================================
|
||||
|
||||
Version 1.02.173 - 09th August 2020
|
||||
===================================
|
||||
Add support for VDO in blkdeactivate script.
|
||||
|
||||
Version 1.02.171 - 26th March 2020
|
||||
==================================
|
||||
Try to remove all created devices on dm preload tree error path.
|
||||
Fix dm_list interators with gcc 10 optimization (-ftree-pta).
|
||||
Dmeventd handles timer without looping on short intervals.
|
||||
|
||||
Version 1.02.169 - 11th February 2020
|
||||
=====================================
|
||||
Enhance error messages for device creation.
|
||||
|
||||
Version 1.02.167 - 30th November 2019
|
||||
=====================================
|
||||
|
||||
Version 1.02.165 - 23rd October 2019
|
||||
====================================
|
||||
@@ -557,7 +534,7 @@ Version 1.02.86 - 23rd June 2014
|
||||
Add DM_REPORT_FIELD_TYPE_STRING_LIST: separate string and string list fields.
|
||||
Add dm_str_list to libdevmapper for string list type definition and its reuse.
|
||||
Add dmsetup -S/--select to define selection criteria for dmsetup reports.
|
||||
Add dm_report_init_with_selection to initialize report with selection criteria.
|
||||
Add dm_report_init_with_selection to intialize report with selection criteria.
|
||||
Add DM_REPORT_FIELD_TYPE_SIZE: separate number and size reporting fields.
|
||||
Use RemoveOnStop for dm-event.socket systemd unit.
|
||||
Document env var 'DM_DEFAULT_NAME_MANGLING_MODE' in dmsetup man page.
|
||||
|
26
aclocal.m4
vendored
26
aclocal.m4
vendored
@@ -1,6 +1,6 @@
|
||||
# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -413,7 +413,7 @@ AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
|
||||
[AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
|
||||
])dnl PKG_HAVE_DEFINE_WITH_MODULES
|
||||
|
||||
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -446,12 +446,10 @@ AC_DEFUN([AM_PATH_PYTHON],
|
||||
[
|
||||
dnl Find a Python interpreter. Python versions prior to 2.0 are not
|
||||
dnl supported. (2.0 was released on October 16, 2000).
|
||||
dnl FIXME: Remove the need to hard-code Python versions here.
|
||||
m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
|
||||
[python python2 python3 dnl
|
||||
python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl
|
||||
python3.2 python3.1 python3.0 dnl
|
||||
python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl
|
||||
python2.0])
|
||||
[python python2 python3 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 dnl
|
||||
python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0])
|
||||
|
||||
AC_ARG_VAR([PYTHON], [the Python interpreter])
|
||||
|
||||
@@ -496,14 +494,12 @@ AC_DEFUN([AM_PATH_PYTHON],
|
||||
m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
|
||||
else
|
||||
|
||||
dnl Query Python for its version number. Although site.py simply uses
|
||||
dnl sys.version[:3], printing that failed with Python 3.10, since the
|
||||
dnl trailing zero was eliminated. So now we output just the major
|
||||
dnl and minor version numbers, as numbers. Apparently the tertiary
|
||||
dnl version is not of interest.
|
||||
dnl Query Python for its version number. Getting [:3] seems to be
|
||||
dnl the best way to do this; it's what "site.py" does in the standard
|
||||
dnl library.
|
||||
|
||||
AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
|
||||
[am_cv_python_version=`$PYTHON -c "import sys; print('%u.%u' % sys.version_info[[:2]])"`])
|
||||
[am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`])
|
||||
AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])
|
||||
|
||||
dnl Use the values of $prefix and $exec_prefix for the corresponding
|
||||
@@ -653,7 +649,7 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
|
||||
sys.exit(sys.hexversion < minverhex)"
|
||||
AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
|
||||
|
||||
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
@@ -22,26 +22,17 @@ struct dm_hash_node {
|
||||
void *data;
|
||||
unsigned data_len;
|
||||
unsigned keylen;
|
||||
unsigned hash;
|
||||
char key[];
|
||||
char key[0];
|
||||
};
|
||||
|
||||
struct dm_hash_table {
|
||||
unsigned num_nodes;
|
||||
unsigned num_hint;
|
||||
unsigned mask_slots; /* (slots - 1) -> used as hash mask */
|
||||
unsigned collisions; /* Collissions of hash keys */
|
||||
unsigned search; /* How many keys were searched */
|
||||
unsigned found; /* How many nodes were found */
|
||||
unsigned same_hash; /* Was there a colision with same masked hash and len ? */
|
||||
unsigned num_slots;
|
||||
struct dm_hash_node **slots;
|
||||
};
|
||||
|
||||
#if 0 /* TO BE REMOVED */
|
||||
static unsigned _hash(const void *key, unsigned len)
|
||||
{
|
||||
/* Permutation of the Integers 0 through 255 */
|
||||
static unsigned char _nums[] = {
|
||||
/* Permutation of the Integers 0 through 255 */
|
||||
static unsigned char _nums[] = {
|
||||
1, 14, 110, 25, 97, 174, 132, 119, 138, 170, 125, 118, 27, 233, 140, 51,
|
||||
87, 197, 177, 107, 234, 169, 56, 68, 30, 7, 173, 73, 188, 40, 36, 65,
|
||||
49, 213, 104, 190, 57, 211, 148, 223, 48, 115, 15, 2, 67, 186, 210, 28,
|
||||
@@ -66,16 +57,29 @@ static unsigned _hash(const void *key, unsigned len)
|
||||
44, 38, 31, 149, 135, 0, 216, 52, 63, 23, 37, 69, 39, 117, 146, 184,
|
||||
163, 200, 222, 235, 248, 243, 219, 10, 152, 131, 123, 229, 203, 76, 120,
|
||||
209
|
||||
};
|
||||
};
|
||||
|
||||
const uint8_t *str = key;
|
||||
unsigned h = 0, g;
|
||||
static struct dm_hash_node *_create_node(const char *str, unsigned len)
|
||||
{
|
||||
struct dm_hash_node *n = malloc(sizeof(*n) + len);
|
||||
|
||||
if (n) {
|
||||
memcpy(n->key, str, len);
|
||||
n->keylen = len;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static unsigned long _hash(const char *str, unsigned len)
|
||||
{
|
||||
unsigned long h = 0, g;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
h <<= 4;
|
||||
h += _nums[*str++];
|
||||
g = h & ((unsigned) 0xf << 16u);
|
||||
h += _nums[(unsigned char) *str++];
|
||||
g = h & ((unsigned long) 0xf << 16u);
|
||||
if (g) {
|
||||
h ^= g >> 16u;
|
||||
h ^= g >> 5u;
|
||||
@@ -85,99 +89,30 @@ static unsigned _hash(const void *key, unsigned len)
|
||||
return h;
|
||||
}
|
||||
|
||||
/* In-kernel DM hashing, still lots of collisions */
|
||||
static unsigned _hash_in_kernel(const char *key, unsigned len)
|
||||
{
|
||||
const unsigned char *str = (unsigned char *)key;
|
||||
const unsigned hash_mult = 2654435387U;
|
||||
unsigned hash = 0, i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
hash = (hash + str[i]) * hash_mult;
|
||||
|
||||
return hash;
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef get16bits
|
||||
#if (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
|
||||
#define get16bits(d) (*((const uint16_t *) (d)))
|
||||
#endif
|
||||
|
||||
#if !defined (get16bits)
|
||||
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
|
||||
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Adapted Bob Jenkins hash to read by 2 bytes if possible.
|
||||
* https://secure.wikimedia.org/wikipedia/en/wiki/Jenkins_hash_function
|
||||
*
|
||||
* Reduces amount of hash collisions
|
||||
*/
|
||||
static unsigned _hash(const void *key, unsigned len)
|
||||
{
|
||||
const uint8_t *str = (uint8_t*) key;
|
||||
unsigned hash = 0, i;
|
||||
unsigned sz = len / 2;
|
||||
|
||||
for(i = 0; i < sz; ++i) {
|
||||
hash += get16bits(str + 2 * i);
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
|
||||
if (len & 1) {
|
||||
hash += str[len - 1];
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
hash += (hash << 15);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static struct dm_hash_node *_create_node(const void *key, unsigned len)
|
||||
{
|
||||
struct dm_hash_node *n = malloc(sizeof(*n) + len);
|
||||
|
||||
if (n) {
|
||||
memcpy(n->key, key, len);
|
||||
n->keylen = len;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
struct dm_hash_table *dm_hash_create(unsigned size_hint)
|
||||
{
|
||||
size_t len;
|
||||
unsigned new_size = 16u;
|
||||
struct dm_hash_table *hc = zalloc(sizeof(*hc));
|
||||
|
||||
if (!hc) {
|
||||
log_error("Failed to allocate memory for hash.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
hc->num_hint = size_hint;
|
||||
if (!hc)
|
||||
return_0;
|
||||
|
||||
/* round size hint up to a power of two */
|
||||
while (new_size < size_hint)
|
||||
new_size = new_size << 1;
|
||||
|
||||
hc->mask_slots = new_size - 1;
|
||||
hc->num_slots = new_size;
|
||||
len = sizeof(*(hc->slots)) * new_size;
|
||||
if (!(hc->slots = zalloc(len))) {
|
||||
free(hc);
|
||||
log_error("Failed to allocate slots for hash.");
|
||||
return 0;
|
||||
}
|
||||
if (!(hc->slots = zalloc(len)))
|
||||
goto_bad;
|
||||
|
||||
return hc;
|
||||
|
||||
bad:
|
||||
free(hc->slots);
|
||||
free(hc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _free_nodes(struct dm_hash_table *t)
|
||||
@@ -185,16 +120,7 @@ static void _free_nodes(struct dm_hash_table *t)
|
||||
struct dm_hash_node *c, *n;
|
||||
unsigned i;
|
||||
|
||||
#ifdef DEBUG
|
||||
log_debug("Free hash hint:%d slots:%d nodes:%d (s:%d f:%d c:%d h:%d)",
|
||||
t->num_hint, t->mask_slots + 1, t->num_nodes,
|
||||
t->search, t->found, t->collisions, t->same_hash);
|
||||
#endif
|
||||
|
||||
if (!t->num_nodes)
|
||||
return;
|
||||
|
||||
for (i = 0; i <= t->mask_slots; i++)
|
||||
for (i = 0; i < t->num_slots; i++)
|
||||
for (c = t->slots[i]; c; c = n) {
|
||||
n = c->next;
|
||||
free(c);
|
||||
@@ -208,30 +134,21 @@ void dm_hash_destroy(struct dm_hash_table *t)
|
||||
free(t);
|
||||
}
|
||||
|
||||
static struct dm_hash_node **_findh(struct dm_hash_table *t, const void *key,
|
||||
uint32_t len, unsigned hash)
|
||||
{
|
||||
struct dm_hash_node **c;
|
||||
|
||||
++t->search;
|
||||
for (c = &t->slots[hash & t->mask_slots]; *c; c = &((*c)->next)) {
|
||||
if ((*c)->keylen == len && (*c)->hash == hash) {
|
||||
if (!memcmp(key, (*c)->key, len)) {
|
||||
++t->found;
|
||||
break;
|
||||
}
|
||||
++t->same_hash;
|
||||
}
|
||||
++t->collisions;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static struct dm_hash_node **_find(struct dm_hash_table *t, const void *key,
|
||||
uint32_t len)
|
||||
{
|
||||
return _findh(t, key, len, _hash(key, len));
|
||||
unsigned h = _hash(key, len) & (t->num_slots - 1);
|
||||
struct dm_hash_node **c;
|
||||
|
||||
for (c = &t->slots[h]; *c; c = &((*c)->next)) {
|
||||
if ((*c)->keylen != len)
|
||||
continue;
|
||||
|
||||
if (!memcmp(key, (*c)->key, len))
|
||||
break;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void *dm_hash_lookup_binary(struct dm_hash_table *t, const void *key,
|
||||
@@ -245,8 +162,7 @@ void *dm_hash_lookup_binary(struct dm_hash_table *t, const void *key,
|
||||
int dm_hash_insert_binary(struct dm_hash_table *t, const void *key,
|
||||
uint32_t len, void *data)
|
||||
{
|
||||
unsigned hash = _hash(key, len);
|
||||
struct dm_hash_node **c = _findh(t, key, len, hash);
|
||||
struct dm_hash_node **c = _find(t, key, len);
|
||||
|
||||
if (*c)
|
||||
(*c)->data = data;
|
||||
@@ -257,7 +173,6 @@ int dm_hash_insert_binary(struct dm_hash_table *t, const void *key,
|
||||
return 0;
|
||||
|
||||
n->data = data;
|
||||
n->hash = hash;
|
||||
n->next = 0;
|
||||
*c = n;
|
||||
t->num_nodes++;
|
||||
@@ -301,7 +216,7 @@ static struct dm_hash_node **_find_str_with_val(struct dm_hash_table *t,
|
||||
struct dm_hash_node **c;
|
||||
unsigned h;
|
||||
|
||||
h = _hash(key, len) & t->mask_slots;
|
||||
h = _hash(key, len) & (t->num_slots - 1);
|
||||
|
||||
for (c = &t->slots[h]; *c; c = &((*c)->next)) {
|
||||
if ((*c)->keylen != len)
|
||||
@@ -332,7 +247,7 @@ int dm_hash_insert_allow_multiple(struct dm_hash_table *t, const char *key,
|
||||
n->data = (void *)val;
|
||||
n->data_len = val_len;
|
||||
|
||||
h = _hash(key, len) & t->mask_slots;
|
||||
h = _hash(key, len) & (t->num_slots - 1);
|
||||
|
||||
first = t->slots[h];
|
||||
|
||||
@@ -400,7 +315,7 @@ void *dm_hash_lookup_with_count(struct dm_hash_table *t, const char *key, int *c
|
||||
|
||||
*count = 0;
|
||||
|
||||
h = _hash(key, len) & t->mask_slots;
|
||||
h = _hash(key, len) & (t->num_slots - 1);
|
||||
|
||||
for (c = &t->slots[h]; *c; c = &((*c)->next)) {
|
||||
if ((*c)->keylen != len)
|
||||
@@ -429,7 +344,7 @@ void dm_hash_iter(struct dm_hash_table *t, dm_hash_iterate_fn f)
|
||||
struct dm_hash_node *c, *n;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i <= t->mask_slots; i++)
|
||||
for (i = 0; i < t->num_slots; i++)
|
||||
for (c = t->slots[i]; c; c = n) {
|
||||
n = c->next;
|
||||
f(c->data);
|
||||
@@ -439,8 +354,8 @@ void dm_hash_iter(struct dm_hash_table *t, dm_hash_iterate_fn f)
|
||||
void dm_hash_wipe(struct dm_hash_table *t)
|
||||
{
|
||||
_free_nodes(t);
|
||||
memset(t->slots, 0, sizeof(struct dm_hash_node *) * (t->mask_slots + 1));
|
||||
t->num_nodes = t->collisions = t->search = t->same_hash = 0u;
|
||||
memset(t->slots, 0, sizeof(struct dm_hash_node *) * t->num_slots);
|
||||
t->num_nodes = 0u;
|
||||
}
|
||||
|
||||
char *dm_hash_get_key(struct dm_hash_table *t __attribute__((unused)),
|
||||
@@ -460,7 +375,7 @@ static struct dm_hash_node *_next_slot(struct dm_hash_table *t, unsigned s)
|
||||
struct dm_hash_node *c = NULL;
|
||||
unsigned i;
|
||||
|
||||
for (i = s; i <= t->mask_slots && !c; i++)
|
||||
for (i = s; i < t->num_slots && !c; i++)
|
||||
c = t->slots[i];
|
||||
|
||||
return c;
|
||||
@@ -473,5 +388,7 @@ struct dm_hash_node *dm_hash_get_first(struct dm_hash_table *t)
|
||||
|
||||
struct dm_hash_node *dm_hash_get_next(struct dm_hash_table *t, struct dm_hash_node *n)
|
||||
{
|
||||
return n->next ? n->next : _next_slot(t, (n->hash & t->mask_slots) + 1);
|
||||
unsigned h = _hash(n->key, n->keylen) & (t->num_slots - 1);
|
||||
|
||||
return n->next ? n->next : _next_slot(t, h + 1);
|
||||
}
|
||||
|
@@ -1,8 +1,6 @@
|
||||
#ifndef BASE_DATA_STRUCT_LIST_H
|
||||
#define BASE_DATA_STRUCT_LIST_H
|
||||
|
||||
#include "base/memory/container_of.h"
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
/*
|
||||
@@ -100,7 +98,7 @@ struct dm_list *dm_list_next(const struct dm_list *head, const struct dm_list *e
|
||||
* contained in a structure of type t, return the containing structure.
|
||||
*/
|
||||
#define dm_list_struct_base(v, t, head) \
|
||||
container_of(v, t, head)
|
||||
((t *)((const char *)(v) - (const char *)&((t *) 0)->head))
|
||||
|
||||
/*
|
||||
* Given the address v of an instance of 'struct dm_list list' contained in
|
||||
@@ -113,7 +111,7 @@ struct dm_list *dm_list_next(const struct dm_list *head, const struct dm_list *e
|
||||
* return another element f.
|
||||
*/
|
||||
#define dm_struct_field(v, t, e, f) \
|
||||
(((t *)((uintptr_t)(v) - offsetof(t, e)))->f)
|
||||
(((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f)
|
||||
|
||||
/*
|
||||
* Given the address v of a known element e in a known structure of type t,
|
||||
|
@@ -47,7 +47,7 @@ struct value_chain {
|
||||
struct prefix_chain {
|
||||
struct value child;
|
||||
unsigned len;
|
||||
uint8_t prefix[];
|
||||
uint8_t prefix[0];
|
||||
};
|
||||
|
||||
struct node4 {
|
||||
@@ -1032,7 +1032,7 @@ void radix_tree_iterate(struct radix_tree *rt, uint8_t *kb, uint8_t *ke,
|
||||
{
|
||||
struct lookup_result lr = _lookup_prefix(&rt->root, kb, ke);
|
||||
if (lr.kb == ke || _prefix_chain_matches(&lr, ke))
|
||||
(void) _iterate(lr.v, it);
|
||||
_iterate(lr.v, it);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2018 - 2020 Red Hat, Inc. All rights reserved.
|
||||
// Copyright (C) 2018 Red Hat, Inc. All rights reserved.
|
||||
//
|
||||
// This file is part of LVM2.
|
||||
//
|
||||
@@ -13,12 +13,10 @@
|
||||
#ifndef BASE_MEMORY_CONTAINER_OF_H
|
||||
#define BASE_MEMORY_CONTAINER_OF_H
|
||||
|
||||
#include <stddef.h> // offsetof
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#define container_of(v, t, head) \
|
||||
((t *)((char *)(v) - offsetof(t, head)))
|
||||
((t *)((const char *)(v) - (const char *)&((t *) 0)->head))
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
|
@@ -78,14 +78,14 @@ devices {
|
||||
# routines to acquire this information. For example, this information
|
||||
# is used to drive LVM filtering like MD component detection, multipath
|
||||
# component detection, partition detection and others.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# none
|
||||
# No external device information source is used.
|
||||
# udev
|
||||
# Reuse existing udev database records. Applicable only if LVM is
|
||||
# compiled with udev support.
|
||||
#
|
||||
#
|
||||
external_device_info_source = "none"
|
||||
|
||||
# Configuration option devices/hints.
|
||||
@@ -94,13 +94,13 @@ devices {
|
||||
# scanning, and will only scan the listed PVs. Removing the hint file
|
||||
# will cause lvm to generate a new one. Disable hints if PVs will
|
||||
# be copied onto devices using non-lvm commands, like dd.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# all
|
||||
# Use all hints.
|
||||
# none
|
||||
# Use no hints.
|
||||
#
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# hints = "all"
|
||||
|
||||
@@ -118,44 +118,12 @@ devices {
|
||||
# Prefer the name with the least number of slashes.
|
||||
# Prefer a name that is a symlink.
|
||||
# Prefer the path with least value in lexicographical order.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
|
||||
#
|
||||
#
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option devices/use_devicesfile.
|
||||
# Enable or disable the use of a devices file.
|
||||
# When enabled, lvm will only use devices that
|
||||
# are lised in the devices file. A devices file will
|
||||
# be used, regardless of this setting, when the --devicesfile
|
||||
# option is set to a specific file name.
|
||||
# This configuration option has an automatic default value.
|
||||
# use_devicesfile = 0
|
||||
|
||||
# Configuration option devices/devicesfile.
|
||||
# The name of the system devices file, listing devices that LVM should use.
|
||||
# This should not be used to select a non-system devices file.
|
||||
# The --devicesfile option is intended for alternative devices files.
|
||||
# This configuration option has an automatic default value.
|
||||
# devicesfile = "system.devices"
|
||||
|
||||
# Configuration option devices/search_for_devnames.
|
||||
# Look outside of the devices file for missing devname entries.
|
||||
# A devname entry is used for a device that does not have a stable
|
||||
# device id, e.g. wwid, so the unstable device name is used as
|
||||
# the device id. After reboot, or if the device is reattached,
|
||||
# the device name may change, in which case lvm will not find
|
||||
# the expected PV on the device listed in the devices file.
|
||||
# This setting controls whether lvm will search other devices,
|
||||
# outside the devices file, to look for the missing PV on a
|
||||
# renamed device. If "none", lvm will not look at other devices,
|
||||
# and the PV may appear to be missing. If "auto", lvm will look
|
||||
# at other devices, but only those that are likely to have the PV.
|
||||
# If "all", lvm will look at all devices on the system.
|
||||
# This configuration option has an automatic default value.
|
||||
# search_for_devnames = "auto"
|
||||
|
||||
# Configuration option devices/filter.
|
||||
# Limit the block devices that are used by LVM commands.
|
||||
# This is a list of regular expressions used to accept or reject block
|
||||
@@ -171,7 +139,7 @@ devices {
|
||||
# then the device is accepted. Be careful mixing 'a' and 'r' patterns,
|
||||
# as the combination might produce unexpected results (test changes.)
|
||||
# Run vgscan after changing the filter to regenerate the cache.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# Accept every block device:
|
||||
# filter = [ "a|.*|" ]
|
||||
@@ -183,7 +151,7 @@ devices {
|
||||
# filter = [ "a|loop|", "r|/dev/hdc|", "a|/dev/ide|", "r|.*|" ]
|
||||
# Use anchors to be very specific:
|
||||
# filter = [ "a|^/dev/hda8$|", "r|.*|" ]
|
||||
#
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# filter = [ "a|.*|" ]
|
||||
|
||||
@@ -201,10 +169,10 @@ devices {
|
||||
# List of additional acceptable block device types.
|
||||
# These are of device type names from /proc/devices, followed by the
|
||||
# maximum number of partitions.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# types = [ "fd", 16 ]
|
||||
#
|
||||
#
|
||||
# This configuration option is advanced.
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
@@ -246,7 +214,7 @@ devices {
|
||||
# Configuration option devices/md_component_checks.
|
||||
# The checks LVM should use to detect MD component devices.
|
||||
# MD component devices are block devices used by MD software RAID.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# auto
|
||||
# LVM will skip scanning the end of devices when it has other
|
||||
@@ -257,7 +225,7 @@ devices {
|
||||
# full
|
||||
# LVM will scan the start and end of devices for MD superblocks.
|
||||
# This requires an extra read at the end of devices.
|
||||
#
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# md_component_checks = "auto"
|
||||
|
||||
@@ -270,16 +238,16 @@ devices {
|
||||
# Configuration option devices/md_chunk_alignment.
|
||||
# Align the start of a PV data area with md device's stripe-width.
|
||||
# This applies if a PV is placed directly on an md device.
|
||||
# default_data_alignment will be overridden if it is not aligned
|
||||
# default_data_alignment will be overriden if it is not aligned
|
||||
# with the value detected for this setting.
|
||||
# This setting is overridden by data_alignment_detection,
|
||||
# This setting is overriden by data_alignment_detection,
|
||||
# data_alignment, and the --dataalignment option.
|
||||
md_chunk_alignment = 1
|
||||
|
||||
# Configuration option devices/default_data_alignment.
|
||||
# Align the start of a PV data area with this number of MiB.
|
||||
# Set to 1 for 1MiB, 2 for 2MiB, etc. Set to 0 to disable.
|
||||
# This setting is overridden by data_alignment and the --dataalignment
|
||||
# This setting is overriden by data_alignment and the --dataalignment
|
||||
# option.
|
||||
# This configuration option has an automatic default value.
|
||||
# default_data_alignment = 1
|
||||
@@ -293,9 +261,9 @@ devices {
|
||||
# preferred unit of receiving I/O, e.g. MD stripe width.
|
||||
# minimum_io_size is used if optimal_io_size is undefined (0).
|
||||
# If md_chunk_alignment is enabled, that detects the optimal_io_size.
|
||||
# default_data_alignment and md_chunk_alignment will be overridden
|
||||
# default_data_alignment and md_chunk_alignment will be overriden
|
||||
# if they are not aligned with the value detected for this setting.
|
||||
# This setting is overridden by data_alignment and the --dataalignment
|
||||
# This setting is overriden by data_alignment and the --dataalignment
|
||||
# option.
|
||||
data_alignment_detection = 1
|
||||
|
||||
@@ -304,7 +272,7 @@ devices {
|
||||
# When non-zero, this setting overrides default_data_alignment.
|
||||
# Set to 0 to disable, in which case default_data_alignment
|
||||
# is used to align the first PE in units of MiB.
|
||||
# This setting is overridden by the --dataalignment option.
|
||||
# This setting is overriden by the --dataalignment option.
|
||||
data_alignment = 0
|
||||
|
||||
# Configuration option devices/data_alignment_offset_detection.
|
||||
@@ -315,7 +283,7 @@ devices {
|
||||
# partitioning will have an alignment_offset of 3584 bytes (sector 7
|
||||
# is the lowest aligned logical block, the 4KiB sectors start at
|
||||
# LBA -1, and consequently sector 63 is aligned on a 4KiB boundary).
|
||||
# This setting is overridden by the --dataalignmentoffset option.
|
||||
# This setting is overriden by the --dataalignmentoffset option.
|
||||
data_alignment_offset_detection = 1
|
||||
|
||||
# Configuration option devices/ignore_suspended_devices.
|
||||
@@ -399,7 +367,7 @@ allocation {
|
||||
# defined here, it will check whether any of them are attached to the
|
||||
# PVs concerned and then seek to match those PV tags between existing
|
||||
# extents and new extents.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# Use the special tag "@*" as a wildcard to match any PV tag:
|
||||
# cling_tag_list = [ "@*" ]
|
||||
@@ -407,7 +375,7 @@ allocation {
|
||||
# PVs are tagged with either @site1 or @site2 to indicate where
|
||||
# they are situated:
|
||||
# cling_tag_list = [ "@site1", "@site2" ]
|
||||
#
|
||||
#
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option allocation/maximise_cling.
|
||||
@@ -461,30 +429,29 @@ allocation {
|
||||
|
||||
# Configuration option allocation/cache_pool_metadata_require_separate_pvs.
|
||||
# Cache pool metadata and data will always use different PVs.
|
||||
# This configuration option has an automatic default value.
|
||||
# cache_pool_metadata_require_separate_pvs = 0
|
||||
cache_pool_metadata_require_separate_pvs = 0
|
||||
|
||||
# Configuration option allocation/cache_metadata_format.
|
||||
# Sets default metadata format for new cache.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# 0 Automatically detected best available format
|
||||
# 1 Original format
|
||||
# 2 Improved 2nd. generation format
|
||||
#
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# cache_metadata_format = 0
|
||||
|
||||
# Configuration option allocation/cache_mode.
|
||||
# The default cache mode used for new cache.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# writethrough
|
||||
# Data blocks are immediately written from the cache to disk.
|
||||
# writeback
|
||||
# Data blocks are written from the cache back to disk after some
|
||||
# delay to improve performance.
|
||||
#
|
||||
#
|
||||
# This setting replaces allocation/cache_pool_cachemode.
|
||||
# This configuration option has an automatic default value.
|
||||
# cache_mode = "writethrough"
|
||||
@@ -521,16 +488,8 @@ allocation {
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option allocation/thin_pool_metadata_require_separate_pvs.
|
||||
# Thin pool metadata and data will always use different PVs.
|
||||
# This configuration option has an automatic default value.
|
||||
# thin_pool_metadata_require_separate_pvs = 0
|
||||
|
||||
# Configuration option allocation/thin_pool_crop_metadata.
|
||||
# Older version of lvm2 cropped pool's metadata size to 15.81 GiB.
|
||||
# This is slightly less then the actual maximum 15.88 GiB.
|
||||
# For compatibility with older version and use of cropped size set to 1.
|
||||
# This configuration option has an automatic default value.
|
||||
# thin_pool_crop_metadata = 0
|
||||
# Thin pool metdata and data will always use different PVs.
|
||||
thin_pool_metadata_require_separate_pvs = 0
|
||||
|
||||
# Configuration option allocation/thin_pool_zero.
|
||||
# Thin pool data chunks are zeroed before they are first used.
|
||||
@@ -540,18 +499,18 @@ allocation {
|
||||
|
||||
# Configuration option allocation/thin_pool_discards.
|
||||
# The discards behaviour of thin pool volumes.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# ignore
|
||||
# nopassdown
|
||||
# passdown
|
||||
#
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# thin_pool_discards = "passdown"
|
||||
|
||||
# Configuration option allocation/thin_pool_chunk_size_policy.
|
||||
# The chunk size calculation policy for thin pool volumes.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# generic
|
||||
# If thin_pool_chunk_size is defined, use it. Otherwise, calculate
|
||||
@@ -563,15 +522,10 @@ allocation {
|
||||
# the chunk size for performance based on device hints exposed in
|
||||
# sysfs - the optimal_io_size. The chunk size is always at least
|
||||
# 512KiB.
|
||||
#
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# thin_pool_chunk_size_policy = "generic"
|
||||
|
||||
# Configuration option allocation/zero_metadata.
|
||||
# Zero whole metadata area before use with thin or cache pool.
|
||||
# This configuration option has an automatic default value.
|
||||
# zero_metadata = 1
|
||||
|
||||
# Configuration option allocation/thin_pool_chunk_size.
|
||||
# The minimal chunk size in KiB for thin pool volumes.
|
||||
# Larger chunk sizes may improve performance for plain thin volumes,
|
||||
@@ -976,7 +930,8 @@ global {
|
||||
# a volume group's metadata, instead of always granting the read-only
|
||||
# requests immediately, delay them to allow the read-write requests to
|
||||
# be serviced. Without this setting, write access may be stalled by a
|
||||
# high volume of read-only requests. This option only affects file locks.
|
||||
# high volume of read-only requests. This option only affects
|
||||
# locking_type 1 viz. local file-based locking.
|
||||
prioritise_write_locks = 1
|
||||
|
||||
# Configuration option global/library_dir.
|
||||
@@ -1000,7 +955,7 @@ global {
|
||||
# Configuration option global/mirror_segtype_default.
|
||||
# The segment type used by the short mirroring option -m.
|
||||
# The --type mirror|raid1 option overrides this setting.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# mirror
|
||||
# The original RAID1 implementation from LVM/DM. It is
|
||||
@@ -1020,19 +975,18 @@ global {
|
||||
# handling a failure. This mirror implementation is not
|
||||
# cluster-aware and cannot be used in a shared (active/active)
|
||||
# fashion in a cluster.
|
||||
#
|
||||
#
|
||||
mirror_segtype_default = "@DEFAULT_MIRROR_SEGTYPE@"
|
||||
|
||||
# Configuration option global/support_mirrored_mirror_log.
|
||||
# Enable mirrored 'mirror' log type for testing.
|
||||
#
|
||||
#
|
||||
# This type is deprecated to create or convert to but can
|
||||
# be enabled to test that activation of existing mirrored
|
||||
# logs and conversion to disk/core works.
|
||||
#
|
||||
#
|
||||
# Not supported for regular operation!
|
||||
# This configuration option has an automatic default value.
|
||||
# support_mirrored_mirror_log = 0
|
||||
support_mirrored_mirror_log = 0
|
||||
|
||||
# Configuration option global/raid10_segtype_default.
|
||||
# The segment type used by the -i -m combination.
|
||||
@@ -1040,7 +994,7 @@ global {
|
||||
# The --stripes/-i and --mirrors/-m options can both be specified
|
||||
# during the creation of a logical volume to use both striping and
|
||||
# mirroring for the LV. There are two different implementations.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# raid10
|
||||
# LVM uses MD's RAID10 personality through DM. This is the
|
||||
@@ -1050,7 +1004,7 @@ global {
|
||||
# is done by creating a mirror LV on top of striped sub-LVs,
|
||||
# effectively creating a RAID 0+1 array. The layering is suboptimal
|
||||
# in terms of providing redundancy and performance.
|
||||
#
|
||||
#
|
||||
raid10_segtype_default = "@DEFAULT_RAID10_SEGTYPE@"
|
||||
|
||||
# Configuration option global/sparse_segtype_default.
|
||||
@@ -1058,7 +1012,7 @@ global {
|
||||
# The --type snapshot|thin option overrides this setting.
|
||||
# The combination of -V and -L options creates a sparse LV. There are
|
||||
# two different implementations.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# snapshot
|
||||
# The original snapshot implementation from LVM/DM. It uses an old
|
||||
@@ -1070,7 +1024,7 @@ global {
|
||||
# bigger minimal chunk size (64KiB) and uses a separate volume for
|
||||
# metadata. It has better performance, especially when more data
|
||||
# is used. It also supports full snapshots.
|
||||
#
|
||||
#
|
||||
sparse_segtype_default = "@DEFAULT_SPARSE_SEGTYPE@"
|
||||
|
||||
# Configuration option global/lvdisplay_shows_full_device_path.
|
||||
@@ -1086,14 +1040,11 @@ global {
|
||||
# Activate LVs based on system-generated device events.
|
||||
# When a device appears on the system, a system-generated event runs
|
||||
# the pvscan command to activate LVs if the new PV completes the VG.
|
||||
# Use auto_activation_volume_list to select which LVs should be
|
||||
# activated from these events (the default is all.)
|
||||
# When event_activation is disabled, the system will generally run
|
||||
# a direct activation command to activate LVs in complete VGs.
|
||||
# Activation commands that are run by the system, either from events
|
||||
# or at fixed points during startup, use autoactivation (-aay). See
|
||||
# the --setautoactivation option or the auto_activation_volume_list
|
||||
# setting to configure autoactivation for specific VGs or LVs.
|
||||
# This configuration option has an automatic default value.
|
||||
# event_activation = 1
|
||||
event_activation = 1
|
||||
|
||||
# Configuration option global/use_aio.
|
||||
# Use async I/O when reading and writing devices.
|
||||
@@ -1124,17 +1075,6 @@ global {
|
||||
# This configuration option has an automatic default value.
|
||||
# sanlock_lv_extend = 256
|
||||
|
||||
# Configuration option global/lvmlockctl_kill_command.
|
||||
# The command that lvmlockctl --kill should use to force LVs offline.
|
||||
# The lvmlockctl --kill command is run when a shared VG has lost
|
||||
# access to locks (e.g. when sanlock has lost access to storage.)
|
||||
# An empty string means that there will be no automatic attempt by
|
||||
# lvmlockctl --kill to forcibly shut down LVs in the VG, and the user
|
||||
# can manually intervene as described in lvmlockd(8).
|
||||
# The VG name will be appended to the command specified here.
|
||||
# This configuration option has an automatic default value.
|
||||
# lvmlockctl_kill_command = ""
|
||||
|
||||
# Configuration option global/thin_check_executable.
|
||||
# The full path to the thin_check command.
|
||||
# LVM uses this command to check that a thin metadata device is in a
|
||||
@@ -1181,20 +1121,20 @@ global {
|
||||
# causing problems. Features include: block_size, discards,
|
||||
# discards_non_power_2, external_origin, metadata_resize,
|
||||
# external_origin_extend, error_if_no_space.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# thin_disabled_features = [ "discards", "block_size" ]
|
||||
#
|
||||
#
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option global/cache_disabled_features.
|
||||
# Features to not use in the cache driver.
|
||||
# This can be helpful for testing, or to avoid using a feature that is
|
||||
# causing problems. Features include: policy_mq, policy_smq, metadata2.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# cache_disabled_features = [ "policy_smq" ]
|
||||
#
|
||||
#
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option global/cache_check_executable.
|
||||
@@ -1246,16 +1186,6 @@ global {
|
||||
# This configuration option has an automatic default value.
|
||||
# vdo_format_options = [ "" ]
|
||||
|
||||
# Configuration option global/vdo_disabled_features.
|
||||
# Features to not use in the vdo driver.
|
||||
# This can be helpful for testing, or to avoid using a feature that is
|
||||
# causing problems. Features include: online_rename
|
||||
#
|
||||
# Example
|
||||
# vdo_disabled_features = [ "online_rename" ]
|
||||
#
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option global/fsadm_executable.
|
||||
# The full path to the fsadm command.
|
||||
# LVM uses this command to help with lvresize -r operations.
|
||||
@@ -1268,7 +1198,7 @@ global {
|
||||
# or vgimport.) A VG on shared storage devices is accessible only to
|
||||
# the host with a matching system ID. See 'man lvmsystemid' for
|
||||
# information on limitations and correct usage.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# none
|
||||
# The host has no system ID.
|
||||
@@ -1285,7 +1215,7 @@ global {
|
||||
# file
|
||||
# Use the contents of another file (system_id_file) to set the
|
||||
# system ID.
|
||||
#
|
||||
#
|
||||
system_id_source = "none"
|
||||
|
||||
# Configuration option global/system_id_file.
|
||||
@@ -1337,7 +1267,7 @@ activation {
|
||||
|
||||
# Configuration option activation/udev_sync.
|
||||
# Use udev notifications to synchronize udev and LVM.
|
||||
# The --noudevsync option overrides this setting.
|
||||
# The --nodevsync option overrides this setting.
|
||||
# When disabled, LVM commands will not wait for notifications from
|
||||
# udev, but continue irrespective of any possible udev processing in
|
||||
# the background. Only use this if udev is not running or has rules
|
||||
@@ -1358,8 +1288,7 @@ activation {
|
||||
# This enables additional checks (and if necessary, repairs) on entries
|
||||
# in the device directory after udev has completed processing its
|
||||
# events. Useful for diagnosing problems with LVM/udev interactions.
|
||||
# This configuration option has an automatic default value.
|
||||
# verify_udev_operations = 0
|
||||
verify_udev_operations = 0
|
||||
|
||||
# Configuration option activation/retry_deactivation.
|
||||
# Retry failed LV deactivation.
|
||||
@@ -1384,34 +1313,30 @@ activation {
|
||||
# When disabled, the striped target is used. The linear target is an
|
||||
# optimised version of the striped target that only handles a single
|
||||
# stripe.
|
||||
# This configuration option has an automatic default value.
|
||||
# use_linear_target = 1
|
||||
use_linear_target = 1
|
||||
|
||||
# Configuration option activation/reserved_stack.
|
||||
# Stack size in KiB to reserve for use while devices are suspended.
|
||||
# Insufficent reserve risks I/O deadlock during device suspension.
|
||||
# This configuration option has an automatic default value.
|
||||
# reserved_stack = 64
|
||||
reserved_stack = 64
|
||||
|
||||
# Configuration option activation/reserved_memory.
|
||||
# Memory size in KiB to reserve for use while devices are suspended.
|
||||
# Insufficent reserve risks I/O deadlock during device suspension.
|
||||
# This configuration option has an automatic default value.
|
||||
# reserved_memory = 8192
|
||||
reserved_memory = 8192
|
||||
|
||||
# Configuration option activation/process_priority.
|
||||
# Nice value used while devices are suspended.
|
||||
# Use a high priority so that LVs are suspended
|
||||
# for the shortest possible time.
|
||||
# This configuration option has an automatic default value.
|
||||
# process_priority = -18
|
||||
process_priority = -18
|
||||
|
||||
# Configuration option activation/volume_list.
|
||||
# Only LVs selected by this list are activated.
|
||||
# If this list is defined, an LV is only activated if it matches an
|
||||
# entry in this list. If this list is undefined, it imposes no limits
|
||||
# on LV activation (all are allowed).
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# vgname
|
||||
# The VG name is matched exactly and selects all LVs in the VG.
|
||||
@@ -1425,30 +1350,30 @@ activation {
|
||||
# or VG. See tags/hosttags. If any host tags exist but volume_list
|
||||
# is not defined, a default single-entry list containing '@*'
|
||||
# is assumed.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
|
||||
#
|
||||
#
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option activation/auto_activation_volume_list.
|
||||
# A list of VGs or LVs that should be autoactivated.
|
||||
# Autoactivation is an activation command run with -aay,
|
||||
# i.e. vgchange -aay, lvchange -aay, or pvscan --cache -aay.
|
||||
# When this list is defined, an autoactivation command will only
|
||||
# activate LVs included in the list. If this list is undefined,
|
||||
# it has no effect. If this list is defined but empty, then no
|
||||
# LVs will be autoactivated. LVs can be included in the list by
|
||||
# LV name, VG name (applies to all LVs in the VG), or tag name.
|
||||
# VGs and LVs can also have an autoactivation property set in
|
||||
# metadata, see --setautoactivation. LVs included in this list
|
||||
# will not be autoactivated if the VG or LV autoactivation
|
||||
# property is disabled (see vgs or lvs "-o autoactivation").
|
||||
# The volume_list setting and the "activation skip" property
|
||||
# also apply to autoactivation.
|
||||
# The -aay option is meant to be used by activation commands that
|
||||
# are run automatically by the system, e.g. from systemd services.
|
||||
#
|
||||
# Only LVs selected by this list are auto-activated.
|
||||
# This list works like volume_list, but it is used only by
|
||||
# auto-activation commands. It does not apply to direct activation
|
||||
# commands. If this list is defined, an LV is only auto-activated
|
||||
# if it matches an entry in this list. If this list is undefined, it
|
||||
# imposes no limits on LV auto-activation (all are allowed.) If this
|
||||
# list is defined and empty, i.e. "[]", then no LVs are selected for
|
||||
# auto-activation. An LV that is selected by this list for
|
||||
# auto-activation, must also be selected by volume_list (if defined)
|
||||
# before it is activated. Auto-activation is an activation command that
|
||||
# includes the 'a' argument: --activate ay or -a ay. The 'a' (auto)
|
||||
# argument for auto-activation is meant to be used by activation
|
||||
# commands that are run automatically by the system, as opposed to LVM
|
||||
# commands run directly by a user. A user may also use the 'a' flag
|
||||
# directly to perform auto-activation. Also see pvscan(8) for more
|
||||
# information about auto-activation.
|
||||
#
|
||||
# Accepted values:
|
||||
# vgname
|
||||
# The VG name is matched exactly and selects all LVs in the VG.
|
||||
@@ -1462,10 +1387,10 @@ activation {
|
||||
# or VG. See tags/hosttags. If any host tags exist but volume_list
|
||||
# is not defined, a default single-entry list containing '@*'
|
||||
# is assumed.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# auto_activation_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
|
||||
#
|
||||
#
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option activation/read_only_volume_list.
|
||||
@@ -1474,7 +1399,7 @@ activation {
|
||||
# against this list, and if it matches, it is activated in read-only
|
||||
# mode. This overrides the permission setting stored in the metadata,
|
||||
# e.g. from --permission rw.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# vgname
|
||||
# The VG name is matched exactly and selects all LVs in the VG.
|
||||
@@ -1488,10 +1413,10 @@ activation {
|
||||
# or VG. See tags/hosttags. If any host tags exist but volume_list
|
||||
# is not defined, a default single-entry list containing '@*'
|
||||
# is assumed.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# read_only_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
|
||||
#
|
||||
#
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option activation/raid_region_size.
|
||||
@@ -1514,15 +1439,14 @@ activation {
|
||||
|
||||
# Configuration option activation/readahead.
|
||||
# Setting to use when there is no readahead setting in metadata.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# none
|
||||
# Disable readahead.
|
||||
# auto
|
||||
# Use default value chosen by kernel.
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# readahead = "auto"
|
||||
#
|
||||
readahead = "auto"
|
||||
|
||||
# Configuration option activation/raid_fault_policy.
|
||||
# Defines how a device failure in a RAID LV is handled.
|
||||
@@ -1532,7 +1456,7 @@ activation {
|
||||
# performed by dmeventd automatically, and the steps perfomed by the
|
||||
# manual command lvconvert --repair --use-policies.
|
||||
# Automatic handling requires dmeventd to be monitoring the LV.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# warn
|
||||
# Use the system log to warn the user that a device in the RAID LV
|
||||
@@ -1543,7 +1467,7 @@ activation {
|
||||
# allocate
|
||||
# Attempt to use any extra physical volumes in the VG as spares and
|
||||
# replace faulty devices.
|
||||
#
|
||||
#
|
||||
raid_fault_policy = "warn"
|
||||
|
||||
# Configuration option activation/mirror_image_fault_policy.
|
||||
@@ -1555,7 +1479,7 @@ activation {
|
||||
# determines the steps perfomed by dmeventd automatically, and the steps
|
||||
# performed by the manual command lvconvert --repair --use-policies.
|
||||
# Automatic handling requires dmeventd to be monitoring the LV.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# remove
|
||||
# Simply remove the faulty device and run without it. If the log
|
||||
@@ -1580,7 +1504,7 @@ activation {
|
||||
# the redundant nature of the mirror. This policy acts like
|
||||
# 'remove' if no suitable device and space can be allocated for the
|
||||
# replacement.
|
||||
#
|
||||
#
|
||||
mirror_image_fault_policy = "remove"
|
||||
|
||||
# Configuration option activation/mirror_log_fault_policy.
|
||||
@@ -1595,26 +1519,26 @@ activation {
|
||||
# The minimum value is 50 (a smaller value is treated as 50.)
|
||||
# Also see snapshot_autoextend_percent.
|
||||
# Automatic extension requires dmeventd to be monitoring the LV.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# Using 70% autoextend threshold and 20% autoextend size, when a 1G
|
||||
# snapshot exceeds 700M, it is extended to 1.2G, and when it exceeds
|
||||
# 840M, it is extended to 1.44G:
|
||||
# snapshot_autoextend_threshold = 70
|
||||
#
|
||||
#
|
||||
snapshot_autoextend_threshold = 100
|
||||
|
||||
# Configuration option activation/snapshot_autoextend_percent.
|
||||
# Auto-extending a snapshot adds this percent extra space.
|
||||
# The amount of additional space added to a snapshot is this
|
||||
# percent of its current size.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# Using 70% autoextend threshold and 20% autoextend size, when a 1G
|
||||
# snapshot exceeds 700M, it is extended to 1.2G, and when it exceeds
|
||||
# 840M, it is extended to 1.44G:
|
||||
# snapshot_autoextend_percent = 20
|
||||
#
|
||||
#
|
||||
snapshot_autoextend_percent = 20
|
||||
|
||||
# Configuration option activation/thin_pool_autoextend_threshold.
|
||||
@@ -1623,26 +1547,26 @@ activation {
|
||||
# The minimum value is 50 (a smaller value is treated as 50.)
|
||||
# Also see thin_pool_autoextend_percent.
|
||||
# Automatic extension requires dmeventd to be monitoring the LV.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# Using 70% autoextend threshold and 20% autoextend size, when a 1G
|
||||
# thin pool exceeds 700M, it is extended to 1.2G, and when it exceeds
|
||||
# 840M, it is extended to 1.44G:
|
||||
# thin_pool_autoextend_threshold = 70
|
||||
#
|
||||
#
|
||||
thin_pool_autoextend_threshold = 100
|
||||
|
||||
# Configuration option activation/thin_pool_autoextend_percent.
|
||||
# Auto-extending a thin pool adds this percent extra space.
|
||||
# The amount of additional space added to a thin pool is this
|
||||
# percent of its current size.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# Using 70% autoextend threshold and 20% autoextend size, when a 1G
|
||||
# thin pool exceeds 700M, it is extended to 1.2G, and when it exceeds
|
||||
# 840M, it is extended to 1.44G:
|
||||
# thin_pool_autoextend_percent = 20
|
||||
#
|
||||
#
|
||||
thin_pool_autoextend_percent = 20
|
||||
|
||||
# Configuration option activation/vdo_pool_autoextend_threshold.
|
||||
@@ -1651,21 +1575,20 @@ activation {
|
||||
# The minimum value is 50 (a smaller value is treated as 50.)
|
||||
# Also see vdo_pool_autoextend_percent.
|
||||
# Automatic extension requires dmeventd to be monitoring the LV.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# Using 70% autoextend threshold and 20% autoextend size, when a 10G
|
||||
# VDO pool exceeds 7G, it is extended to 12G, and when it exceeds
|
||||
# 8.4G, it is extended to 14.4G:
|
||||
# vdo_pool_autoextend_threshold = 70
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# vdo_pool_autoextend_threshold = 100
|
||||
#
|
||||
vdo_pool_autoextend_threshold = 100
|
||||
|
||||
# Configuration option activation/vdo_pool_autoextend_percent.
|
||||
# Auto-extending a VDO pool adds this percent extra space.
|
||||
# The amount of additional space added to a VDO pool is this
|
||||
# percent of its current size.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# Using 70% autoextend threshold and 20% autoextend size, when a 10G
|
||||
# VDO pool exceeds 7G, it is extended to 12G, and when it exceeds
|
||||
@@ -1684,10 +1607,10 @@ activation {
|
||||
# pages corresponding to lines that match are not pinned. On some
|
||||
# systems, locale-archive was found to make up over 80% of the memory
|
||||
# used by the process.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# mlock_filter = [ "locale/locale-archive", "gconv/gconv-modules.cache" ]
|
||||
#
|
||||
#
|
||||
# This configuration option is advanced.
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
@@ -1695,8 +1618,7 @@ activation {
|
||||
# Use the old behavior of mlockall to pin all memory.
|
||||
# Prior to version 2.02.62, LVM used mlockall() to pin the whole
|
||||
# process's memory while activating devices.
|
||||
# This configuration option has an automatic default value.
|
||||
# use_mlockall = 0
|
||||
use_mlockall = 0
|
||||
|
||||
# Configuration option activation/monitoring.
|
||||
# Monitor LVs that are activated.
|
||||
@@ -1711,8 +1633,7 @@ activation {
|
||||
# intervals of this number of seconds. If this is set to 0 and there
|
||||
# is only one thing to wait for, there are no progress reports, but
|
||||
# the process is awoken immediately once the operation is complete.
|
||||
# This configuration option has an automatic default value.
|
||||
# polling_interval = 15
|
||||
polling_interval = 15
|
||||
|
||||
# Configuration option activation/auto_set_activation_skip.
|
||||
# Set the activation skip flag on new thin snapshot LVs.
|
||||
@@ -1728,7 +1649,7 @@ activation {
|
||||
# Configuration option activation/activation_mode.
|
||||
# How LVs with missing devices are activated.
|
||||
# The --activationmode option overrides this setting.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# complete
|
||||
# Only allow activation of an LV if all of the Physical Volumes it
|
||||
@@ -1743,7 +1664,7 @@ activation {
|
||||
# could cause data loss with a portion of the LV inaccessible.
|
||||
# This setting should not normally be used, but may sometimes
|
||||
# assist with data recovery.
|
||||
#
|
||||
#
|
||||
activation_mode = "degraded"
|
||||
|
||||
# Configuration option activation/lock_start_list.
|
||||
@@ -1791,7 +1712,7 @@ activation {
|
||||
# Configuration option metadata/pvmetadatacopies.
|
||||
# Number of copies of metadata to store on each PV.
|
||||
# The --pvmetadatacopies option overrides this setting.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# 2
|
||||
# Two copies of the VG metadata are stored on the PV, one at the
|
||||
@@ -1801,7 +1722,7 @@ activation {
|
||||
# 0
|
||||
# No copies of VG metadata are stored on the PV. This may be
|
||||
# useful for VGs containing large numbers of PVs.
|
||||
#
|
||||
#
|
||||
# This configuration option is advanced.
|
||||
# This configuration option has an automatic default value.
|
||||
# pvmetadatacopies = 1
|
||||
@@ -1951,7 +1872,7 @@ activation {
|
||||
# sequences are copied verbatim. Each special character sequence is
|
||||
# introduced by the '%' character and such sequence is then
|
||||
# substituted with a value as described below.
|
||||
#
|
||||
#
|
||||
# Accepted values:
|
||||
# %a
|
||||
# The abbreviated name of the day of the week according to the
|
||||
@@ -2074,7 +1995,7 @@ activation {
|
||||
# The timezone name or abbreviation.
|
||||
# %%
|
||||
# A literal '%' character.
|
||||
#
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# time_format = "%Y-%m-%d %T %z"
|
||||
|
||||
@@ -2268,8 +2189,7 @@ dmeventd {
|
||||
# failures. It removes failed devices from a volume group and
|
||||
# reconfigures a mirror as necessary. If no mirror library is
|
||||
# provided, mirrors are not monitored through dmeventd.
|
||||
# This configuration option has an automatic default value.
|
||||
# mirror_library = "libdevmapper-event-lvm2mirror.so"
|
||||
mirror_library = "libdevmapper-event-lvm2mirror.so"
|
||||
|
||||
# Configuration option dmeventd/raid_library.
|
||||
# This configuration option has an automatic default value.
|
||||
@@ -2280,16 +2200,14 @@ dmeventd {
|
||||
# libdevmapper-event-lvm2snapshot.so monitors the filling of snapshots
|
||||
# and emits a warning through syslog when the usage exceeds 80%. The
|
||||
# warning is repeated when 85%, 90% and 95% of the snapshot is filled.
|
||||
# This configuration option has an automatic default value.
|
||||
# snapshot_library = "libdevmapper-event-lvm2snapshot.so"
|
||||
snapshot_library = "libdevmapper-event-lvm2snapshot.so"
|
||||
|
||||
# Configuration option dmeventd/thin_library.
|
||||
# The library dmeventd uses when monitoring a thin device.
|
||||
# libdevmapper-event-lvm2thin.so monitors the filling of a pool
|
||||
# and emits a warning through syslog when the usage exceeds 80%. The
|
||||
# warning is repeated when 85%, 90% and 95% of the pool is filled.
|
||||
# This configuration option has an automatic default value.
|
||||
# thin_library = "libdevmapper-event-lvm2thin.so"
|
||||
thin_library = "libdevmapper-event-lvm2thin.so"
|
||||
|
||||
# Configuration option dmeventd/thin_command.
|
||||
# The plugin runs command with each 5% increment when thin-pool data volume
|
||||
@@ -2343,12 +2261,12 @@ dmeventd {
|
||||
# applied to the local machine as a 'host tag'. If this subsection is
|
||||
# empty (has no host_list), then the subsection name is always applied
|
||||
# as a 'host tag'.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# The host tag foo is given to all hosts, and the host tag
|
||||
# bar is given to the hosts named machine1 and machine2.
|
||||
# tags { foo { } bar { host_list = [ "machine1", "machine2" ] } }
|
||||
#
|
||||
#
|
||||
# This configuration section has variable name.
|
||||
# This configuration section has an automatic default value.
|
||||
# tag {
|
||||
|
@@ -28,13 +28,13 @@ local {
|
||||
# main configuration file, e.g. lvm.conf. When used, it must be set to
|
||||
# a unique value among all hosts sharing access to the storage,
|
||||
# e.g. a host name.
|
||||
#
|
||||
#
|
||||
# Example
|
||||
# Set no system ID:
|
||||
# system_id = ""
|
||||
# Set the system_id to a specific name:
|
||||
# system_id = "host1"
|
||||
#
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# system_id = ""
|
||||
|
||||
|
344
configure
vendored
344
configure
vendored
@@ -640,7 +640,6 @@ LVMLOCKD_PIDFILE
|
||||
LVMPOLLD_PIDFILE
|
||||
DMEVENTD_PIDFILE
|
||||
WRITE_INSTALL
|
||||
WRITECACHE
|
||||
VDO_LIB
|
||||
VDO_INCLUDE
|
||||
VDO
|
||||
@@ -703,7 +702,6 @@ LIB_SUFFIX
|
||||
LDDEPS
|
||||
JOBS
|
||||
INTL
|
||||
INTEGRITY
|
||||
HAVE_VALGRIND
|
||||
HAVE_REALTIME
|
||||
HAVE_LIBDL
|
||||
@@ -755,8 +753,6 @@ BUILD_CMIRRORD
|
||||
BLKID_PC
|
||||
MODPROBE_CMD
|
||||
MSGFMT
|
||||
EDITLINE_LIBS
|
||||
EDITLINE_CFLAGS
|
||||
PYTHON3_CONFIG
|
||||
pkgpyexecdir
|
||||
pyexecdir
|
||||
@@ -797,8 +793,6 @@ PKGCONFIGINIT_CFLAGS
|
||||
PKG_CONFIG_LIBDIR
|
||||
PKG_CONFIG_PATH
|
||||
PKG_CONFIG
|
||||
AIO_LIBS
|
||||
AIO_CFLAGS
|
||||
VDO_FORMAT_CMD
|
||||
CACHE_RESTORE_CMD
|
||||
CACHE_REPAIR_CMD
|
||||
@@ -872,7 +866,6 @@ infodir
|
||||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
@@ -925,9 +918,7 @@ enable_cache_check_needs_check
|
||||
with_vdo
|
||||
with_vdo_format
|
||||
with_writecache
|
||||
with_integrity
|
||||
enable_readline
|
||||
enable_editline
|
||||
enable_realtime
|
||||
enable_ocf
|
||||
with_ocfdir
|
||||
@@ -938,7 +929,6 @@ enable_cmirrord
|
||||
with_cmirrord_pidfile
|
||||
enable_debug
|
||||
with_optimisation
|
||||
with_symvers
|
||||
enable_profiling
|
||||
enable_valgrind_pool
|
||||
enable_devmapper
|
||||
@@ -969,7 +959,6 @@ enable_fsadm
|
||||
enable_blkdeactivate
|
||||
enable_dmeventd
|
||||
enable_selinux
|
||||
enable_blkzeroout
|
||||
enable_nls
|
||||
with_localedir
|
||||
with_confdir
|
||||
@@ -1002,8 +991,6 @@ CXX
|
||||
CXXFLAGS
|
||||
CCC
|
||||
CPP
|
||||
AIO_CFLAGS
|
||||
AIO_LIBS
|
||||
PKG_CONFIG
|
||||
PKG_CONFIG_PATH
|
||||
PKG_CONFIG_LIBDIR
|
||||
@@ -1027,9 +1014,7 @@ SYSTEMD_CFLAGS
|
||||
SYSTEMD_LIBS
|
||||
UDEV_CFLAGS
|
||||
UDEV_LIBS
|
||||
PYTHON
|
||||
EDITLINE_CFLAGS
|
||||
EDITLINE_LIBS'
|
||||
PYTHON'
|
||||
|
||||
|
||||
# Initialize some variables set by options.
|
||||
@@ -1068,7 +1053,6 @@ datadir='${datarootdir}'
|
||||
sysconfdir='${prefix}/etc'
|
||||
sharedstatedir='${prefix}/com'
|
||||
localstatedir='${prefix}/var'
|
||||
runstatedir='${localstatedir}/run'
|
||||
includedir='${prefix}/include'
|
||||
oldincludedir='/usr/include'
|
||||
docdir='${datarootdir}/doc/${PACKAGE}'
|
||||
@@ -1321,15 +1305,6 @@ do
|
||||
| -silent | --silent | --silen | --sile | --sil)
|
||||
silent=yes ;;
|
||||
|
||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
||||
| --run | --ru | --r)
|
||||
ac_prev=runstatedir ;;
|
||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
||||
| --run=* | --ru=* | --r=*)
|
||||
runstatedir=$ac_optarg ;;
|
||||
|
||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||
ac_prev=sbindir ;;
|
||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||
@@ -1467,7 +1442,7 @@ fi
|
||||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||
libdir localedir mandir runstatedir
|
||||
libdir localedir mandir
|
||||
do
|
||||
eval ac_val=\$$ac_var
|
||||
# Remove trailing slashes.
|
||||
@@ -1620,7 +1595,6 @@ Fine tuning of the installation directories:
|
||||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||
--includedir=DIR C header files [PREFIX/include]
|
||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||
@@ -1663,7 +1637,6 @@ Optional Features:
|
||||
--disable-cache_check_needs_check
|
||||
required if cache_check version is < 0.5
|
||||
--disable-readline disable readline support
|
||||
--enable-editline enable editline support
|
||||
--disable-realtime disable realtime clock support
|
||||
--enable-ocf enable Open Cluster Framework (OCF) compliant
|
||||
resource agents
|
||||
@@ -1704,7 +1677,6 @@ Optional Features:
|
||||
--disable-blkdeactivate disable blkdeactivate
|
||||
--enable-dmeventd enable the device-mapper event daemon
|
||||
--disable-selinux disable selinux support
|
||||
--disable-blkzeroout do not use BLKZEROOUT for device zeroing
|
||||
--enable-nls enable Native Language Support
|
||||
|
||||
Optional Packages:
|
||||
@@ -1719,21 +1691,22 @@ Optional Packages:
|
||||
create nodes on resume or create [ON=resume]
|
||||
--with-default-name-mangling=MANGLING
|
||||
default name mangling: auto/none/hex [auto]
|
||||
--with-snapshots=TYPE snapshot support: internal/none [internal]
|
||||
--with-mirrors=TYPE mirror support: internal/none [internal]
|
||||
--with-snapshots=TYPE snapshot support: internal/shared/none [internal]
|
||||
--with-mirrors=TYPE mirror support: internal/shared/none [internal]
|
||||
--with-default-mirror-segtype=TYPE
|
||||
default mirror segtype: raid1/mirror [raid1]
|
||||
--with-default-raid10-segtype=TYPE
|
||||
default mirror segtype: raid10/mirror [raid10]
|
||||
--with-default-sparse-segtype=TYPE
|
||||
default sparse segtype: thin/snapshot [thin]
|
||||
--with-thin=TYPE thin provisioning support: internal/none [internal]
|
||||
--with-thin=TYPE thin provisioning support: internal/shared/none
|
||||
[internal]
|
||||
--with-thin-check=PATH thin_check tool: [autodetect]
|
||||
--with-thin-dump=PATH thin_dump tool: [autodetect]
|
||||
--with-thin-repair=PATH thin_repair tool: [autodetect]
|
||||
--with-thin-restore=PATH
|
||||
thin_restore tool: [autodetect]
|
||||
--with-cache=TYPE cache support: internal/none [internal]
|
||||
--with-cache=TYPE cache support: internal/shared/none [internal]
|
||||
--with-cache-check=PATH cache_check tool: [autodetect]
|
||||
--with-cache-dump=PATH cache_dump tool: [autodetect]
|
||||
--with-cache-repair=PATH
|
||||
@@ -1742,21 +1715,18 @@ Optional Packages:
|
||||
cache_restore tool: [autodetect]
|
||||
--with-vdo=TYPE vdo support: internal/none [internal]
|
||||
--with-vdo-format=PATH vdoformat tool: [autodetect]
|
||||
--with-writecache=TYPE writecache support: internal/none [internal]
|
||||
--with-integrity=TYPE integrity support: internal/none [internal]
|
||||
--with-writecache=TYPE writecache support: internal/none [none]
|
||||
--with-ocfdir=DIR install OCF files in
|
||||
[PREFIX/lib/ocf/resource.d/lvm2]
|
||||
--with-default-pid-dir=PID_DIR
|
||||
default directory to keep PID files in [autodetect]
|
||||
Default directory to keep PID files in. [autodetect]
|
||||
--with-default-dm-run-dir=DM_RUN_DIR
|
||||
default DM run directory [autodetect]
|
||||
Default DM run directory. [autodetect]
|
||||
--with-default-run-dir=RUN_DIR
|
||||
default LVM run directory [autodetect_run_dir/lvm]
|
||||
Default LVM run directory. [autodetect_run_dir/lvm]
|
||||
--with-cmirrord-pidfile=PATH
|
||||
cmirrord pidfile [PID_DIR/cmirrord.pid]
|
||||
--with-optimisation=OPT C optimisation flag [OPT=-O2]
|
||||
--with-symvers=STYLE use symbol versioning of the shared library
|
||||
[default=gnu]
|
||||
--with-lvmlockd-pidfile=PATH
|
||||
lvmlockd pidfile [PID_DIR/lvmlockd.pid]
|
||||
--with-lvmpolld-pidfile=PATH
|
||||
@@ -1803,8 +1773,6 @@ Some influential environment variables:
|
||||
CXX C++ compiler command
|
||||
CXXFLAGS C++ compiler flags
|
||||
CPP C preprocessor
|
||||
AIO_CFLAGS C compiler flags for AIO
|
||||
AIO_LIBS linker flags for AIO
|
||||
PKG_CONFIG path to pkg-config utility
|
||||
PKG_CONFIG_PATH
|
||||
directories to add to pkg-config's search path
|
||||
@@ -1846,10 +1814,6 @@ Some influential environment variables:
|
||||
UDEV_CFLAGS C compiler flags for UDEV, overriding pkg-config
|
||||
UDEV_LIBS linker flags for UDEV, overriding pkg-config
|
||||
PYTHON the Python interpreter
|
||||
EDITLINE_CFLAGS
|
||||
C compiler flags for EDITLINE, overriding pkg-config
|
||||
EDITLINE_LIBS
|
||||
linker flags for EDITLINE, overriding pkg-config
|
||||
|
||||
Use these variables to override the choices made by `configure' or to help
|
||||
it to find libraries and programs with nonstandard names/locations.
|
||||
@@ -3113,11 +3077,13 @@ if test -z "$CFLAGS"; then :
|
||||
fi
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"} -Wl,--version-script,.export.sym"
|
||||
# equivalent to -rdynamic
|
||||
ELDFLAGS="-Wl,--export-dynamic"
|
||||
# FIXME Generate list and use --dynamic-list=.dlopen.sym
|
||||
CLDWHOLEARCHIVE="-Wl,-whole-archive"
|
||||
CLDNOWHOLEARCHIVE="-Wl,-no-whole-archive"
|
||||
LDDEPS="$LDDEPS .export.sym"
|
||||
LIB_SUFFIX=so
|
||||
DEVMAPPER=yes
|
||||
BUILD_LVMPOLLD=no
|
||||
@@ -3132,6 +3098,7 @@ case "$host_os" in
|
||||
;;
|
||||
darwin*)
|
||||
CFLAGS="$CFLAGS -no-cpp-precomp -fno-common"
|
||||
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"}"
|
||||
ELDFLAGS=
|
||||
CLDWHOLEARCHIVE="-all_load"
|
||||
CLDNOWHOLEARCHIVE=
|
||||
@@ -6096,7 +6063,7 @@ fi
|
||||
|
||||
|
||||
for ac_header in assert.h ctype.h dirent.h errno.h fcntl.h float.h \
|
||||
getopt.h inttypes.h langinfo.h libgen.h limits.h locale.h paths.h \
|
||||
getopt.h inttypes.h langinfo.h libaio.h libgen.h limits.h locale.h paths.h \
|
||||
signal.h stdarg.h stddef.h stdio.h stdlib.h string.h sys/file.h \
|
||||
sys/ioctl.h syslog.h sys/mman.h sys/param.h sys/resource.h sys/stat.h \
|
||||
sys/time.h sys/types.h sys/utsname.h sys/wait.h time.h \
|
||||
@@ -6129,19 +6096,6 @@ fi
|
||||
|
||||
done
|
||||
|
||||
for ac_header in libaio.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "libaio.h" "ac_cv_header_libaio_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_libaio_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBAIO_H 1
|
||||
_ACEOF
|
||||
LVM_NEEDS_LIBAIO_WARN=
|
||||
else
|
||||
LVM_NEEDS_LIBAIO_WARN=y
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
@@ -8405,7 +8359,7 @@ fi
|
||||
|
||||
case "$MANGLING" in
|
||||
auto) mangling=DM_STRING_MANGLING_AUTO;;
|
||||
no|none|disabled) mangling=DM_STRING_MANGLING_NONE;;
|
||||
none|disabled) mangling=DM_STRING_MANGLING_NONE;;
|
||||
hex) mangling=DM_STRING_MANGLING_HEX;;
|
||||
*) as_fn_error $? "--with-default-name-mangling parameter invalid" "$LINENO" 5;;
|
||||
esac
|
||||
@@ -8432,7 +8386,7 @@ fi
|
||||
$as_echo "$SNAPSHOTS" >&6; }
|
||||
|
||||
case "$SNAPSHOTS" in
|
||||
no|none|shared) ;;
|
||||
none|shared) ;;
|
||||
internal)
|
||||
$as_echo "#define SNAPSHOT_INTERNAL 1" >>confdefs.h
|
||||
;;
|
||||
@@ -8454,7 +8408,7 @@ fi
|
||||
$as_echo "$MIRRORS" >&6; }
|
||||
|
||||
case "$MIRRORS" in
|
||||
no|none|shared) ;;
|
||||
none|shared) ;;
|
||||
internal)
|
||||
$as_echo "#define MIRRORED_INTERNAL 1" >>confdefs.h
|
||||
;;
|
||||
@@ -8499,10 +8453,7 @@ _ACEOF
|
||||
|
||||
# Check whether --with-default-sparse-segtype was given.
|
||||
if test "${with_default_sparse_segtype+set}" = set; then :
|
||||
withval=$with_default_sparse_segtype; case "$withval" in
|
||||
thin|snapshot) DEFAULT_SPARSE_SEGTYPE=$withval ;;
|
||||
*) as_fn_error $? "--with-default-sparse-segtype parameter invalid" "$LINENO" 5 ;;
|
||||
esac
|
||||
withval=$with_default_sparse_segtype; DEFAULT_SPARSE_SEGTYPE=$withval
|
||||
else
|
||||
DEFAULT_SPARSE_SEGTYPE="thin"
|
||||
fi
|
||||
@@ -8556,7 +8507,7 @@ fi
|
||||
$as_echo "$THIN" >&6; }
|
||||
|
||||
case "$THIN" in
|
||||
no|none) test "$DEFAULT_SPARSE_SEGTYPE" = "thin" && DEFAULT_SPARSE_SEGTYPE="snapshot" ;;
|
||||
none) test "$DEFAULT_SPARSE_SEGTYPE" = "thin" && DEFAULT_SPARSE_SEGTYPE="snapshot" ;;
|
||||
shared) ;;
|
||||
internal)
|
||||
$as_echo "#define THIN_INTERNAL 1" >>confdefs.h
|
||||
@@ -9037,6 +8988,7 @@ $as_echo "$THIN_CHECK_NEEDS_CHECK" >&6; }
|
||||
$as_echo "#define THIN_CHECK_NEEDS_CHECK 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -9111,7 +9063,7 @@ fi
|
||||
$as_echo "$CACHE" >&6; }
|
||||
|
||||
case "$CACHE" in
|
||||
no|none|shared) ;;
|
||||
none|shared) ;;
|
||||
internal)
|
||||
$as_echo "#define CACHE_INTERNAL 1" >>confdefs.h
|
||||
;;
|
||||
@@ -9632,7 +9584,7 @@ $as_echo_n "checking whether to include vdo... " >&6; }
|
||||
if test "${with_vdo+set}" = set; then :
|
||||
withval=$with_vdo; VDO=$withval
|
||||
else
|
||||
VDO="internal"
|
||||
VDO="none"
|
||||
fi
|
||||
|
||||
|
||||
@@ -9648,7 +9600,7 @@ else
|
||||
fi
|
||||
|
||||
case "$VDO" in
|
||||
no|none) ;;
|
||||
none) ;;
|
||||
internal)
|
||||
|
||||
$as_echo "#define VDO_INTERNAL 1" >>confdefs.h
|
||||
@@ -9792,7 +9744,7 @@ $as_echo_n "checking whether to include writecache... " >&6; }
|
||||
if test "${with_writecache+set}" = set; then :
|
||||
withval=$with_writecache; WRITECACHE=$withval
|
||||
else
|
||||
WRITECACHE="internal"
|
||||
WRITECACHE="none"
|
||||
fi
|
||||
|
||||
|
||||
@@ -9800,7 +9752,7 @@ fi
|
||||
$as_echo "$WRITECACHE" >&6; }
|
||||
|
||||
case "$WRITECACHE" in
|
||||
no|none) ;;
|
||||
none) ;;
|
||||
internal)
|
||||
|
||||
$as_echo "#define WRITECACHE_INTERNAL 1" >>confdefs.h
|
||||
@@ -9809,39 +9761,6 @@ $as_echo "#define WRITECACHE_INTERNAL 1" >>confdefs.h
|
||||
*) as_fn_error $? "--with-writecache parameter invalid" "$LINENO" 5 ;;
|
||||
esac
|
||||
|
||||
################################################################################
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include integrity" >&5
|
||||
$as_echo_n "checking whether to include integrity... " >&6; }
|
||||
|
||||
# Check whether --with-integrity was given.
|
||||
if test "${with_integrity+set}" = set; then :
|
||||
withval=$with_integrity; INTEGRITY=$withval
|
||||
else
|
||||
INTEGRITY="internal"
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTEGRITY" >&5
|
||||
$as_echo "$INTEGRITY" >&6; }
|
||||
|
||||
case "$INTEGRITY" in
|
||||
no|none) ;;
|
||||
internal)
|
||||
|
||||
$as_echo "#define INTEGRITY_INTERNAL 1" >>confdefs.h
|
||||
|
||||
;;
|
||||
*) as_fn_error $? "--with-integrity parameter invalid" "$LINENO" 5 ;;
|
||||
esac
|
||||
|
||||
################################################################################
|
||||
# Allow users to override default location for libaio
|
||||
# there seems to be no pkg-config support available
|
||||
AIO_CFLAGS=
|
||||
AIO_LIBS=${AIO_LIBS:--laio}
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
# Check whether --enable-readline was given.
|
||||
if test "${enable_readline+set}" = set; then :
|
||||
@@ -9851,15 +9770,6 @@ else
|
||||
fi
|
||||
|
||||
|
||||
################################################################################
|
||||
# Check whether --enable-editline was given.
|
||||
if test "${enable_editline+set}" = set; then :
|
||||
enableval=$enable_editline; EDITLINE=$enableval
|
||||
else
|
||||
EDITLINE=no
|
||||
fi
|
||||
|
||||
|
||||
################################################################################
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable realtime support" >&5
|
||||
$as_echo_n "checking whether to enable realtime support... " >&6; }
|
||||
@@ -10423,35 +10333,6 @@ fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $COPTIMISE_FLAG" >&5
|
||||
$as_echo "$COPTIMISE_FLAG" >&6; }
|
||||
|
||||
################################################################################
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use symbol versioning" >&5
|
||||
$as_echo_n "checking whether to use symbol versioning... " >&6; }
|
||||
|
||||
# Check whether --with-symvers was given.
|
||||
if test "${with_symvers+set}" = set; then :
|
||||
withval=$with_symvers; case "$withval" in
|
||||
gnu|no) symvers=$withval ;;
|
||||
*) as_fn_error $? "--with-symvers parameter invalid" "$LINENO" 5 ;;
|
||||
esac
|
||||
else
|
||||
symvers=gnu
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $symvers" >&5
|
||||
$as_echo "$symvers" >&6; }
|
||||
|
||||
if test "$GCC" = "yes" && test "$symvers" = "gnu" ; then
|
||||
|
||||
$as_echo "#define GNU_SYMVER 1" >>confdefs.h
|
||||
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"} -Wl,--version-script,.export.sym"
|
||||
LDDEPS="$LDDEPS .export.sym"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to gather gcov profiling data" >&5
|
||||
$as_echo_n "checking whether to gather gcov profiling data... " >&6; }
|
||||
@@ -10788,6 +10669,7 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable valgrind awareness of pools" >&5
|
||||
$as_echo_n "checking whether to enable valgrind awareness of pools... " >&6; }
|
||||
@@ -11915,7 +11797,6 @@ if test "$BUILD_LVMDBUSD" = yes; then
|
||||
|
||||
|
||||
|
||||
|
||||
if test -n "$PYTHON"; then
|
||||
# If the user set $PYTHON, use it and don't search something else.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 3" >&5
|
||||
@@ -11951,7 +11832,7 @@ if ${am_cv_pathless_PYTHON+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
|
||||
for am_cv_pathless_PYTHON in python3 python2 python python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do
|
||||
for am_cv_pathless_PYTHON in python python2 python3 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do
|
||||
test "$am_cv_pathless_PYTHON" = none && break
|
||||
prog="import sys
|
||||
# split strings by '.' and convert to numeric. Append some zeros
|
||||
@@ -12032,7 +11913,7 @@ $as_echo_n "checking for $am_display_PYTHON version... " >&6; }
|
||||
if ${am_cv_python_version+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
am_cv_python_version=`$PYTHON -c "import sys; print('%u.%u' % sys.version_info[:2])"`
|
||||
am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"`
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5
|
||||
$as_echo "$am_cv_python_version" >&6; }
|
||||
@@ -12780,61 +12661,6 @@ fi
|
||||
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BLKZEROOUT in sys/ioctl.h." >&5
|
||||
$as_echo_n "checking for BLKZEROOUT in sys/ioctl.h.... " >&6; }
|
||||
if ${ac_cv_have_blkzeroout+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
int bar(void) { return ioctl(0, BLKZEROOUT, 0); }
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
ac_cv_have_blkzeroout=yes
|
||||
else
|
||||
ac_cv_have_blkzeroout=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_blkzeroout" >&5
|
||||
$as_echo "$ac_cv_have_blkzeroout" >&6; }
|
||||
|
||||
|
||||
# Check whether --enable-blkzeroout was given.
|
||||
if test "${enable_blkzeroout+set}" = set; then :
|
||||
enableval=$enable_blkzeroout; BLKZEROOUT=$enableval
|
||||
else
|
||||
BLKZEROOUT=yes
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use BLKZEROOUT for device zeroing" >&5
|
||||
$as_echo_n "checking whether to use BLKZEROOUT for device zeroing... " >&6; }
|
||||
if test "$BLKZEROOUT" = yes; then
|
||||
if test $ac_cv_have_blkzeroout = yes; then :
|
||||
|
||||
$as_echo "#define HAVE_BLKZEROOUT 1" >>confdefs.h
|
||||
|
||||
else
|
||||
BLKZEROOUT=no
|
||||
fi
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BLKZEROOUT" >&5
|
||||
$as_echo "$BLKZEROOUT" >&6; }
|
||||
|
||||
|
||||
################################################################################
|
||||
RT_LIBS=
|
||||
HAVE_REALTIME=no
|
||||
@@ -12955,86 +12781,6 @@ fi
|
||||
done
|
||||
|
||||
|
||||
################################################################################
|
||||
if test "$EDITLINE" == yes; then
|
||||
|
||||
pkg_failed=no
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EDITLINE" >&5
|
||||
$as_echo_n "checking for EDITLINE... " >&6; }
|
||||
|
||||
if test -n "$EDITLINE_CFLAGS"; then
|
||||
pkg_cv_EDITLINE_CFLAGS="$EDITLINE_CFLAGS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libedit\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libedit") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_EDITLINE_CFLAGS=`$PKG_CONFIG --cflags "libedit" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
if test -n "$EDITLINE_LIBS"; then
|
||||
pkg_cv_EDITLINE_LIBS="$EDITLINE_LIBS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libedit\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libedit") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_EDITLINE_LIBS=`$PKG_CONFIG --libs "libedit" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||
_pkg_short_errors_supported=yes
|
||||
else
|
||||
_pkg_short_errors_supported=no
|
||||
fi
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
EDITLINE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libedit" 2>&1`
|
||||
else
|
||||
EDITLINE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libedit" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$EDITLINE_PKG_ERRORS" >&5
|
||||
|
||||
as_fn_error $? "libedit could not be found which is required for the --enable-editline option." "$LINENO" 5
|
||||
|
||||
elif test $pkg_failed = untried; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
as_fn_error $? "libedit could not be found which is required for the --enable-editline option." "$LINENO" 5
|
||||
|
||||
else
|
||||
EDITLINE_CFLAGS=$pkg_cv_EDITLINE_CFLAGS
|
||||
EDITLINE_LIBS=$pkg_cv_EDITLINE_LIBS
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
|
||||
|
||||
$as_echo "#define EDITLINE_SUPPORT 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
if test "$READLINE" != no; then
|
||||
lvm_saved_libs=$LIBS
|
||||
@@ -13473,27 +13219,6 @@ $as_echo_n "checking whether to enable readline... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $READLINE" >&5
|
||||
$as_echo "$READLINE" >&6; }
|
||||
|
||||
if test "$EDITLINE" = yes; then
|
||||
for ac_header in editline/readline.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_editline_readline_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_EDITLINE_READLINE_H 1
|
||||
_ACEOF
|
||||
|
||||
else
|
||||
hard_bailout
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable editline" >&5
|
||||
$as_echo_n "checking whether to enable editline... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $EDITLINE" >&5
|
||||
$as_echo "$EDITLINE" >&6; }
|
||||
|
||||
if test "$BUILD_CMIRRORD" = yes; then
|
||||
for ac_func in atexit
|
||||
do :
|
||||
@@ -14173,9 +13898,6 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15550,14 +15272,10 @@ $as_echo "$as_me: WARNING: You should install latest cache_check vsn 0.7.0 to us
|
||||
fi
|
||||
|
||||
if test -n "$VDO_CONFIGURE_WARN"; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unrecognized 'vdoformat' tool is REQUIRED for VDO logical volume creation!" >&5
|
||||
$as_echo "$as_me: WARNING: Unrecognized 'vdoformat' tool is REQUIRED for VDO logical volume creation!" >&2;}
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized 'vdoformat' tool is REQUIRED for VDO logical volume creation!" >&5
|
||||
$as_echo "$as_me: WARNING: unrecognized 'vdoformat' tool is REQUIRED for VDO logical volume creation!" >&2;}
|
||||
fi
|
||||
|
||||
if test -n "$LVM_NEEDS_LIBAIO_WARN"; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Only libdm part can be build without libaio: make [install_]device-mapper" >&5
|
||||
$as_echo "$as_me: WARNING: Only libdm part can be build without libaio: make [install_]device-mapper" >&2;}
|
||||
fi
|
||||
|
||||
if test "$ODIRECT" != yes; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: O_DIRECT disabled: low-memory pvmove may lock up" >&5
|
||||
|
162
configure.ac
162
configure.ac
@@ -30,11 +30,13 @@ AC_CANONICAL_TARGET([])
|
||||
AS_IF([test -z "$CFLAGS"], [COPTIMISE_FLAG="-O2"])
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"} -Wl,--version-script,.export.sym"
|
||||
# equivalent to -rdynamic
|
||||
ELDFLAGS="-Wl,--export-dynamic"
|
||||
# FIXME Generate list and use --dynamic-list=.dlopen.sym
|
||||
CLDWHOLEARCHIVE="-Wl,-whole-archive"
|
||||
CLDNOWHOLEARCHIVE="-Wl,-no-whole-archive"
|
||||
LDDEPS="$LDDEPS .export.sym"
|
||||
LIB_SUFFIX=so
|
||||
DEVMAPPER=yes
|
||||
BUILD_LVMPOLLD=no
|
||||
@@ -49,6 +51,7 @@ case "$host_os" in
|
||||
;;
|
||||
darwin*)
|
||||
CFLAGS="$CFLAGS -no-cpp-precomp -fno-common"
|
||||
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"}"
|
||||
ELDFLAGS=
|
||||
CLDWHOLEARCHIVE="-all_load"
|
||||
CLDNOWHOLEARCHIVE=
|
||||
@@ -101,14 +104,14 @@ AC_HEADER_SYS_WAIT
|
||||
AC_HEADER_TIME
|
||||
|
||||
AC_CHECK_HEADERS([assert.h ctype.h dirent.h errno.h fcntl.h float.h \
|
||||
getopt.h inttypes.h langinfo.h libgen.h limits.h locale.h paths.h \
|
||||
getopt.h inttypes.h langinfo.h libaio.h libgen.h limits.h locale.h paths.h \
|
||||
signal.h stdarg.h stddef.h stdio.h stdlib.h string.h sys/file.h \
|
||||
sys/ioctl.h syslog.h sys/mman.h sys/param.h sys/resource.h sys/stat.h \
|
||||
sys/time.h sys/types.h sys/utsname.h sys/wait.h time.h \
|
||||
unistd.h], , [AC_MSG_ERROR(bailing out)])
|
||||
|
||||
AC_CHECK_HEADERS(termios.h sys/statvfs.h sys/timerfd.h sys/vfs.h linux/magic.h linux/fiemap.h)
|
||||
AC_CHECK_HEADERS(libaio.h,LVM_NEEDS_LIBAIO_WARN=,LVM_NEEDS_LIBAIO_WARN=y)
|
||||
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
AC_CHECK_HEADERS(asm/byteorder.h linux/fs.h malloc.h,,AC_MSG_ERROR(bailing out)) ;;
|
||||
@@ -289,7 +292,7 @@ AC_ARG_WITH(default-name-mangling,
|
||||
MANGLING=$withval, MANGLING=auto)
|
||||
case "$MANGLING" in
|
||||
auto) mangling=DM_STRING_MANGLING_AUTO;;
|
||||
no|none|disabled) mangling=DM_STRING_MANGLING_NONE;;
|
||||
none|disabled) mangling=DM_STRING_MANGLING_NONE;;
|
||||
hex) mangling=DM_STRING_MANGLING_HEX;;
|
||||
*) AC_MSG_ERROR([--with-default-name-mangling parameter invalid]);;
|
||||
esac
|
||||
@@ -301,12 +304,12 @@ dnl -- snapshots inclusion type
|
||||
AC_MSG_CHECKING(whether to include snapshots)
|
||||
AC_ARG_WITH(snapshots,
|
||||
AC_HELP_STRING([--with-snapshots=TYPE],
|
||||
[snapshot support: internal/none [internal]]),
|
||||
[snapshot support: internal/shared/none [internal]]),
|
||||
SNAPSHOTS=$withval, SNAPSHOTS=internal)
|
||||
AC_MSG_RESULT($SNAPSHOTS)
|
||||
|
||||
case "$SNAPSHOTS" in
|
||||
no|none|shared) ;;
|
||||
none|shared) ;;
|
||||
internal) AC_DEFINE([SNAPSHOT_INTERNAL], 1,
|
||||
[Define to 1 to include built-in support for snapshots.]) ;;
|
||||
*) AC_MSG_ERROR([--with-snapshots parameter invalid]) ;;
|
||||
@@ -317,12 +320,12 @@ dnl -- mirrors inclusion type
|
||||
AC_MSG_CHECKING(whether to include mirrors)
|
||||
AC_ARG_WITH(mirrors,
|
||||
AC_HELP_STRING([--with-mirrors=TYPE],
|
||||
[mirror support: internal/none [internal]]),
|
||||
[mirror support: internal/shared/none [internal]]),
|
||||
MIRRORS=$withval, MIRRORS=internal)
|
||||
AC_MSG_RESULT($MIRRORS)
|
||||
|
||||
case "$MIRRORS" in
|
||||
no|none|shared) ;;
|
||||
none|shared) ;;
|
||||
internal) AC_DEFINE([MIRRORED_INTERNAL], 1,
|
||||
[Define to 1 to include built-in support for mirrors.]) ;;
|
||||
*) AC_MSG_ERROR([--with-mirrors parameter invalid]) ;;
|
||||
@@ -352,17 +355,14 @@ AC_DEFINE_UNQUOTED([DEFAULT_RAID10_SEGTYPE], ["$DEFAULT_RAID10_SEGTYPE"],
|
||||
AC_ARG_WITH(default-sparse-segtype,
|
||||
AC_HELP_STRING([--with-default-sparse-segtype=TYPE],
|
||||
[default sparse segtype: thin/snapshot [thin]]),
|
||||
[ case "$withval" in
|
||||
thin|snapshot) DEFAULT_SPARSE_SEGTYPE=$withval ;;
|
||||
*) AC_MSG_ERROR(--with-default-sparse-segtype parameter invalid) ;;
|
||||
esac], DEFAULT_SPARSE_SEGTYPE="thin")
|
||||
DEFAULT_SPARSE_SEGTYPE=$withval, DEFAULT_SPARSE_SEGTYPE="thin")
|
||||
|
||||
################################################################################
|
||||
dnl -- thin provisioning
|
||||
AC_MSG_CHECKING(whether to include thin provisioning)
|
||||
AC_ARG_WITH(thin,
|
||||
AC_HELP_STRING([--with-thin=TYPE],
|
||||
[thin provisioning support: internal/none [internal]]),
|
||||
[thin provisioning support: internal/shared/none [internal]]),
|
||||
THIN=$withval, THIN=internal)
|
||||
AC_ARG_WITH(thin-check,
|
||||
AC_HELP_STRING([--with-thin-check=PATH],
|
||||
@@ -384,7 +384,7 @@ AC_ARG_WITH(thin-restore,
|
||||
AC_MSG_RESULT($THIN)
|
||||
|
||||
case "$THIN" in
|
||||
no|none) test "$DEFAULT_SPARSE_SEGTYPE" = "thin" && DEFAULT_SPARSE_SEGTYPE="snapshot" ;;
|
||||
none) test "$DEFAULT_SPARSE_SEGTYPE" = "thin" && DEFAULT_SPARSE_SEGTYPE="snapshot" ;;
|
||||
shared) ;;
|
||||
internal) AC_DEFINE([THIN_INTERNAL], 1,
|
||||
[Define to 1 to include built-in support for thin provisioning.]) ;;
|
||||
@@ -461,6 +461,7 @@ case "$THIN" in
|
||||
if test "$THIN_CHECK_NEEDS_CHECK" = yes; then
|
||||
AC_DEFINE([THIN_CHECK_NEEDS_CHECK], 1, [Define to 1 if the external 'thin_check' tool requires the --clear-needs-check-flag option])
|
||||
fi
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -481,7 +482,7 @@ dnl -- cache inclusion type
|
||||
AC_MSG_CHECKING(whether to include cache)
|
||||
AC_ARG_WITH(cache,
|
||||
AC_HELP_STRING([--with-cache=TYPE],
|
||||
[cache support: internal/none [internal]]),
|
||||
[cache support: internal/shared/none [internal]]),
|
||||
CACHE=$withval, CACHE="internal")
|
||||
AC_ARG_WITH(cache-check,
|
||||
AC_HELP_STRING([--with-cache-check=PATH],
|
||||
@@ -502,7 +503,7 @@ AC_ARG_WITH(cache-restore,
|
||||
AC_MSG_RESULT($CACHE)
|
||||
|
||||
case "$CACHE" in
|
||||
no|none|shared) ;;
|
||||
none|shared) ;;
|
||||
internal) AC_DEFINE([CACHE_INTERNAL], 1, [Define to 1 to include built-in support for cache.]) ;;
|
||||
*) AC_MSG_ERROR([--with-cache parameter invalid]) ;;
|
||||
esac
|
||||
@@ -606,7 +607,7 @@ AC_MSG_CHECKING(whether to include vdo)
|
||||
AC_ARG_WITH(vdo,
|
||||
AC_HELP_STRING([--with-vdo=TYPE],
|
||||
[vdo support: internal/none [internal]]),
|
||||
VDO=$withval, VDO="internal")
|
||||
VDO=$withval, VDO="none")
|
||||
|
||||
AC_MSG_RESULT($VDO)
|
||||
|
||||
@@ -615,8 +616,8 @@ AC_ARG_WITH(vdo-format,
|
||||
[vdoformat tool: [autodetect]]),
|
||||
VDO_FORMAT_CMD=$withval, VDO_FORMAT_CMD="autodetect")
|
||||
case "$VDO" in
|
||||
no|none) ;;
|
||||
internal)
|
||||
none) ;;
|
||||
internal)
|
||||
AC_DEFINE([VDO_INTERNAL], 1, [Define to 1 to include built-in support for vdo.])
|
||||
if test "$VDO_FORMAT_CMD" = "autodetect"; then
|
||||
AC_PATH_TOOL(VDO_FORMAT_CMD, vdoformat, [], [$PATH])
|
||||
@@ -645,7 +646,7 @@ AC_DEFINE_UNQUOTED([VDO_FORMAT_CMD], ["$VDO_FORMAT_CMD"],
|
||||
#AC_ARG_WITH(vdo-lib,
|
||||
# AC_HELP_STRING([--with-vdo-lib=PATH],
|
||||
# [vdo support: Path to utils lib: [/usr/lib]]),
|
||||
# VDO_LIB=$withval, VDO_LIB="/usr/lib")
|
||||
# VDO_LIB=$withval, VDO_LIB="/usr/lib")
|
||||
#AC_MSG_RESULT($VDO_LIB)
|
||||
|
||||
################################################################################
|
||||
@@ -653,57 +654,25 @@ dnl -- writecache inclusion type
|
||||
AC_MSG_CHECKING(whether to include writecache)
|
||||
AC_ARG_WITH(writecache,
|
||||
AC_HELP_STRING([--with-writecache=TYPE],
|
||||
[writecache support: internal/none [internal]]),
|
||||
WRITECACHE=$withval, WRITECACHE="internal")
|
||||
[writecache support: internal/none [none]]),
|
||||
WRITECACHE=$withval, WRITECACHE="none")
|
||||
|
||||
AC_MSG_RESULT($WRITECACHE)
|
||||
|
||||
case "$WRITECACHE" in
|
||||
no|none) ;;
|
||||
internal)
|
||||
none) ;;
|
||||
internal)
|
||||
AC_DEFINE([WRITECACHE_INTERNAL], 1, [Define to 1 to include built-in support for writecache.])
|
||||
;;
|
||||
*) AC_MSG_ERROR([--with-writecache parameter invalid]) ;;
|
||||
esac
|
||||
|
||||
################################################################################
|
||||
dnl -- integrity inclusion type
|
||||
AC_MSG_CHECKING(whether to include integrity)
|
||||
AC_ARG_WITH(integrity,
|
||||
AC_HELP_STRING([--with-integrity=TYPE],
|
||||
[integrity support: internal/none [internal]]),
|
||||
INTEGRITY=$withval, INTEGRITY="internal")
|
||||
|
||||
AC_MSG_RESULT($INTEGRITY)
|
||||
|
||||
case "$INTEGRITY" in
|
||||
no|none) ;;
|
||||
internal)
|
||||
AC_DEFINE([INTEGRITY_INTERNAL], 1, [Define to 1 to include built-in support for integrity.])
|
||||
;;
|
||||
*) AC_MSG_ERROR([--with-integrity parameter invalid]) ;;
|
||||
esac
|
||||
|
||||
################################################################################
|
||||
# Allow users to override default location for libaio
|
||||
# there seems to be no pkg-config support available
|
||||
AIO_CFLAGS=
|
||||
AIO_LIBS=${AIO_LIBS:--laio}
|
||||
AC_ARG_VAR([AIO_CFLAGS], [C compiler flags for AIO])
|
||||
AC_ARG_VAR([AIO_LIBS], [linker flags for AIO])
|
||||
|
||||
################################################################################
|
||||
dnl -- Disable readline
|
||||
AC_ARG_ENABLE([readline],
|
||||
AC_HELP_STRING([--disable-readline], [disable readline support]),
|
||||
READLINE=$enableval, READLINE=maybe)
|
||||
|
||||
################################################################################
|
||||
dnl -- Disable editline
|
||||
AC_ARG_ENABLE([editline],
|
||||
AC_HELP_STRING([--enable-editline], [enable editline support]),
|
||||
EDITLINE=$enableval, EDITLINE=no)
|
||||
|
||||
################################################################################
|
||||
dnl -- Disable realtime clock support
|
||||
AC_MSG_CHECKING(whether to enable realtime support)
|
||||
@@ -747,7 +716,7 @@ dnl -- Set up pidfile and run directory
|
||||
AH_TEMPLATE(DEFAULT_PID_DIR)
|
||||
AC_ARG_WITH(default-pid-dir,
|
||||
AC_HELP_STRING([--with-default-pid-dir=PID_DIR],
|
||||
[default directory to keep PID files in [autodetect]]),
|
||||
[Default directory to keep PID files in. [autodetect]]),
|
||||
DEFAULT_PID_DIR="$withval", DEFAULT_PID_DIR=$RUN_DIR)
|
||||
AC_DEFINE_UNQUOTED(DEFAULT_PID_DIR, ["$DEFAULT_PID_DIR"],
|
||||
[Default directory to keep PID files in.])
|
||||
@@ -755,7 +724,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_PID_DIR, ["$DEFAULT_PID_DIR"],
|
||||
AH_TEMPLATE(DEFAULT_DM_RUN_DIR, [Name of default DM run directory.])
|
||||
AC_ARG_WITH(default-dm-run-dir,
|
||||
AC_HELP_STRING([--with-default-dm-run-dir=DM_RUN_DIR],
|
||||
[default DM run directory [autodetect]]),
|
||||
[ Default DM run directory. [autodetect]]),
|
||||
DEFAULT_DM_RUN_DIR="$withval", DEFAULT_DM_RUN_DIR=$RUN_DIR)
|
||||
AC_DEFINE_UNQUOTED(DEFAULT_DM_RUN_DIR, ["$DEFAULT_DM_RUN_DIR"],
|
||||
[Default DM run directory.])
|
||||
@@ -763,7 +732,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_DM_RUN_DIR, ["$DEFAULT_DM_RUN_DIR"],
|
||||
AH_TEMPLATE(DEFAULT_RUN_DIR, [Name of default LVM run directory.])
|
||||
AC_ARG_WITH(default-run-dir,
|
||||
AC_HELP_STRING([--with-default-run-dir=RUN_DIR],
|
||||
[default LVM run directory [autodetect_run_dir/lvm]]),
|
||||
[Default LVM run directory. [autodetect_run_dir/lvm]]),
|
||||
DEFAULT_RUN_DIR="$withval", DEFAULT_RUN_DIR="$RUN_DIR/lvm")
|
||||
AC_DEFINE_UNQUOTED(DEFAULT_RUN_DIR, ["$DEFAULT_RUN_DIR"],
|
||||
[Default LVM run directory.])
|
||||
@@ -832,29 +801,6 @@ AC_ARG_WITH(optimisation,
|
||||
COPTIMISE_FLAG=$withval)
|
||||
AC_MSG_RESULT($COPTIMISE_FLAG)
|
||||
|
||||
################################################################################
|
||||
dnl -- Symbol versioning
|
||||
AC_MSG_CHECKING(whether to use symbol versioning)
|
||||
AC_ARG_WITH(symvers,
|
||||
AC_HELP_STRING([--with-symvers=STYLE],
|
||||
[use symbol versioning of the shared library [default=gnu]]),
|
||||
[ case "$withval" in
|
||||
gnu|no) symvers=$withval ;;
|
||||
*) AC_MSG_ERROR(--with-symvers parameter invalid) ;;
|
||||
esac], symvers=gnu)
|
||||
AC_MSG_RESULT($symvers)
|
||||
|
||||
if test "$GCC" = "yes" && test "$symvers" = "gnu" ; then
|
||||
AC_DEFINE(GNU_SYMVER, 1,
|
||||
[Define to use GNU versioning in the shared library.])
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"} -Wl,--version-script,.export.sym"
|
||||
LDDEPS="$LDDEPS .export.sym"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable profiling
|
||||
AC_MSG_CHECKING(whether to gather gcov profiling data)
|
||||
@@ -889,6 +835,7 @@ TESTSUITE_DATA='${datarootdir}/lvm2-testsuite'
|
||||
# double eval needed ${datarootdir} -> ${prefix}/share -> real path
|
||||
AC_DEFINE_UNQUOTED(TESTSUITE_DATA, ["$(eval echo $(eval echo $TESTSUITE_DATA))"], [Path to testsuite data])
|
||||
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable valgrind awareness of memory pools
|
||||
AC_MSG_CHECKING(whether to enable valgrind awareness of pools)
|
||||
@@ -1253,9 +1200,6 @@ if test "$BUILD_LVMDBUSD" = yes; then
|
||||
unset am_cv_pathless_PYTHON ac_cv_path_PYTHON am_cv_python_platform
|
||||
unset am_cv_python_pythondir am_cv_python_version am_cv_python_pyexecdir
|
||||
unset ac_cv_path_PYTHON_CONFIG ac_cv_path_ac_pt_PYTHON_CONFIG
|
||||
m4_define_default([_AM_PYTHON_INTERPRETER_LIST],[ python3 python2 python dnl
|
||||
python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 dnl
|
||||
python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 ])
|
||||
AM_PATH_PYTHON([3])
|
||||
PYTHON3=$PYTHON
|
||||
test -z "$PYTHON3" && AC_MSG_ERROR([python3 is required for --enable-python3_bindings or --enable-dbus-service but cannot be found])
|
||||
@@ -1383,33 +1327,6 @@ if test "$SELINUX" = yes; then
|
||||
HAVE_SELINUX=no ])
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Check BLKZEROOUT support
|
||||
|
||||
AC_CACHE_CHECK([for BLKZEROOUT in sys/ioctl.h.],
|
||||
[ac_cv_have_blkzeroout],
|
||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||
[#include <sys/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
int bar(void) { return ioctl(0, BLKZEROOUT, 0); }]
|
||||
)], [ac_cv_have_blkzeroout=yes], [ac_cv_have_blkzeroout=no])])
|
||||
|
||||
|
||||
AC_ARG_ENABLE(blkzeroout,
|
||||
AC_HELP_STRING([--disable-blkzeroout],
|
||||
[do not use BLKZEROOUT for device zeroing]),
|
||||
BLKZEROOUT=$enableval, BLKZEROOUT=yes)
|
||||
|
||||
AC_MSG_CHECKING(whether to use BLKZEROOUT for device zeroing)
|
||||
if test "$BLKZEROOUT" = yes; then
|
||||
AC_IF_YES(ac_cv_have_blkzeroout,
|
||||
AC_DEFINE(HAVE_BLKZEROOUT, 1,
|
||||
[Define if ioctl BLKZEROOUT can be used for device zeroing.]),
|
||||
BLKZEROOUT=no)
|
||||
fi
|
||||
AC_MSG_RESULT($BLKZEROOUT)
|
||||
|
||||
|
||||
################################################################################
|
||||
dnl -- Check for realtime clock support
|
||||
RT_LIBS=
|
||||
@@ -1443,16 +1360,6 @@ AC_IF_YES(ac_cv_stat_st_ctim,
|
||||
dnl -- Check for getopt
|
||||
AC_CHECK_HEADERS(getopt.h, AC_DEFINE([HAVE_GETOPTLONG], 1, [Define to 1 if getopt_long is available.]))
|
||||
|
||||
################################################################################
|
||||
dnl -- Check for editline
|
||||
if test "$EDITLINE" == yes; then
|
||||
PKG_CHECK_MODULES([EDITLINE], [libedit], [
|
||||
AC_DEFINE([EDITLINE_SUPPORT], 1,
|
||||
[Define to 1 to include the LVM editline shell.])], AC_MSG_ERROR(
|
||||
[libedit could not be found which is required for the --enable-editline option.])
|
||||
)
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Check for readline (Shamelessly copied from parted 1.4.17)
|
||||
if test "$READLINE" != no; then
|
||||
@@ -1585,12 +1492,6 @@ fi
|
||||
AC_MSG_CHECKING(whether to enable readline)
|
||||
AC_MSG_RESULT($READLINE)
|
||||
|
||||
if test "$EDITLINE" = yes; then
|
||||
AC_CHECK_HEADERS(editline/readline.h,,hard_bailout)
|
||||
fi
|
||||
AC_MSG_CHECKING(whether to enable editline)
|
||||
AC_MSG_RESULT($EDITLINE)
|
||||
|
||||
if test "$BUILD_CMIRRORD" = yes; then
|
||||
AC_CHECK_FUNCS(atexit,,hard_bailout)
|
||||
fi
|
||||
@@ -1808,7 +1709,6 @@ AC_SUBST(BLKDEACTIVATE)
|
||||
AC_SUBST(HAVE_LIBDL)
|
||||
AC_SUBST(HAVE_REALTIME)
|
||||
AC_SUBST(HAVE_VALGRIND)
|
||||
AC_SUBST(INTEGRITY)
|
||||
AC_SUBST(INTL)
|
||||
AC_SUBST(JOBS)
|
||||
AC_SUBST(LDDEPS)
|
||||
@@ -1847,7 +1747,6 @@ AC_SUBST(QUORUM_CFLAGS)
|
||||
AC_SUBST(QUORUM_LIBS)
|
||||
AC_SUBST(RT_LIBS)
|
||||
AC_SUBST(READLINE_LIBS)
|
||||
AC_SUBST(EDITLINE_LIBS)
|
||||
AC_SUBST(REPLICATORS)
|
||||
AC_SUBST(SACKPT_CFLAGS)
|
||||
AC_SUBST(SACKPT_LIBS)
|
||||
@@ -1885,7 +1784,6 @@ AC_SUBST(VDO)
|
||||
AC_SUBST(VDO_FORMAT_CMD)
|
||||
AC_SUBST(VDO_INCLUDE)
|
||||
AC_SUBST(VDO_LIB)
|
||||
AC_SUBST(WRITECACHE)
|
||||
AC_SUBST(WRITE_INSTALL)
|
||||
AC_SUBST(DMEVENTD_PIDFILE)
|
||||
AC_SUBST(LVMPOLLD_PIDFILE)
|
||||
@@ -1984,10 +1882,8 @@ AS_IF([test -n "$CACHE_CHECK_VERSION_WARN"],
|
||||
[AC_MSG_WARN([You should install latest cache_check vsn 0.7.0 to use lvm2 cache metadata format 2])])
|
||||
|
||||
AS_IF([test -n "$VDO_CONFIGURE_WARN"],
|
||||
[AC_MSG_WARN([Unrecognized 'vdoformat' tool is REQUIRED for VDO logical volume creation!])])
|
||||
[AC_MSG_WARN([unrecognized 'vdoformat' tool is REQUIRED for VDO logical volume creation!])])
|
||||
|
||||
AS_IF([test -n "$LVM_NEEDS_LIBAIO_WARN"],
|
||||
[AC_MSG_WARN([Only libdm part can be build without libaio: make [[install_]]device-mapper])])
|
||||
|
||||
AS_IF([test "$ODIRECT" != yes],
|
||||
[AC_MSG_WARN([O_DIRECT disabled: low-memory pvmove may lock up])])
|
||||
|
@@ -46,7 +46,6 @@ const char *find_config_tree_str(struct cmd_context *cmd, int id, struct profile
|
||||
return "STRING";
|
||||
}
|
||||
|
||||
/*
|
||||
struct logical_volume *origin_from_cow(const struct logical_volume *lv)
|
||||
{
|
||||
if (lv)
|
||||
@@ -54,7 +53,6 @@ struct logical_volume *origin_from_cow(const struct logical_volume *lv)
|
||||
|
||||
__coverity_panic__();
|
||||
}
|
||||
*/
|
||||
|
||||
/* simple_memccpy() from glibc */
|
||||
void *memccpy(void *dest, const void *src, int c, size_t n)
|
||||
|
@@ -22,9 +22,6 @@ SOURCES = clogd.c cluster.c compat.c functions.c link_mon.c local.c logging.c
|
||||
|
||||
TARGETS = cmirrord
|
||||
|
||||
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
|
||||
CFLOW_TARGET := $(TARGETS)
|
||||
|
||||
include $(top_builddir)/make.tmpl
|
||||
|
||||
LMLIBS += $(CPG_LIBS)
|
||||
@@ -36,8 +33,6 @@ cmirrord: $(OBJECTS)
|
||||
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \
|
||||
$(LMLIBS) -L$(top_builddir)/libdm -ldevmapper $(LIBS)
|
||||
|
||||
install_cluster: $(TARGETS)
|
||||
install: $(TARGETS)
|
||||
@echo " [INSTALL] $<"
|
||||
$(Q) $(INSTALL_PROGRAM) -D $< $(usrsbindir)/$(<F)
|
||||
|
||||
install: install_cluster
|
||||
$(Q) $(INSTALL_PROGRAM) -D cmirrord $(usrsbindir)/cmirrord
|
||||
|
@@ -1548,7 +1548,7 @@ static void cpg_config_callback(cpg_handle_t handle, const struct cpg_name *gnam
|
||||
member_list, member_list_entries);
|
||||
}
|
||||
|
||||
static cpg_callbacks_t cpg_callbacks = {
|
||||
cpg_callbacks_t cpg_callbacks = {
|
||||
.cpg_deliver_fn = cpg_message_callback,
|
||||
.cpg_confchg_fn = cpg_config_callback,
|
||||
};
|
||||
|
@@ -39,7 +39,7 @@ struct clog_request {
|
||||
* machine. If the two are equal, there is no need
|
||||
* to do endian conversions.
|
||||
*/
|
||||
union version_u {
|
||||
union {
|
||||
uint64_t version[2]; /* LE version and native version */
|
||||
struct dm_list list;
|
||||
} u;
|
||||
|
@@ -658,7 +658,8 @@ static int clog_dtr(struct dm_ulog_request *rq)
|
||||
if (lc->disk_fd != -1 && close(lc->disk_fd))
|
||||
LOG_ERROR("Failed to close disk log: %s",
|
||||
strerror(errno));
|
||||
free(lc->disk_buffer);
|
||||
if (lc->disk_buffer)
|
||||
free(lc->disk_buffer);
|
||||
free(lc->clean_bits);
|
||||
free(lc->sync_bits);
|
||||
free(lc);
|
||||
|
@@ -14,21 +14,11 @@
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
top_builddir = @top_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
|
||||
SOURCES = libdevmapper-event.c
|
||||
SOURCES2 = dmeventd.c
|
||||
|
||||
TARGETS = dmeventd
|
||||
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES) $(SOURCES2) \
|
||||
plugins/lvm2/dmeventd_lvm.c \
|
||||
plugins/mirror/dmeventd_mirror.c \
|
||||
plugins/raid/dmeventd_raid.c \
|
||||
plugins/snapshot/dmeventd_snapshot.c \
|
||||
plugins/thin/dmeventd_thin.c \
|
||||
plugins/vdo/dmeventd_vdo.c \
|
||||
)
|
||||
CFLOW_TARGET := $(TARGETS)
|
||||
|
||||
.PHONY: install_lib_dynamic install_lib_static install_include \
|
||||
install_pkgconfig install_dmeventd_dynamic install_dmeventd_static \
|
||||
@@ -47,7 +37,6 @@ endif
|
||||
|
||||
LIB_VERSION = $(LIB_VERSION_DM)
|
||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
|
||||
LIBS = $(PTHREAD_LIBS) -L$(interfacebuilddir) -ldevmapper
|
||||
|
||||
CLEAN_TARGETS = dmeventd.static $(LIB_NAME).a
|
||||
|
||||
@@ -57,6 +46,7 @@ endif
|
||||
|
||||
CFLOW_LIST = $(SOURCES)
|
||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
|
||||
CFLOW_TARGET = dmeventd
|
||||
|
||||
EXPORTED_HEADER = $(srcdir)/libdevmapper-event.h
|
||||
EXPORTED_FN_PREFIX = dm_event
|
||||
@@ -65,26 +55,34 @@ include $(top_builddir)/make.tmpl
|
||||
|
||||
all: device-mapper
|
||||
device-mapper: $(TARGETS)
|
||||
plugins.device-mapper: $(LIB_SHARED)
|
||||
|
||||
CFLAGS_dmeventd.o += $(EXTRA_EXEC_CFLAGS)
|
||||
LIBS += $(PTHREAD_LIBS) -L$(top_builddir)/libdm -ldevmapper
|
||||
|
||||
dmeventd: $(LIB_SHARED) dmeventd.o
|
||||
@echo " [CC] $@"
|
||||
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) dmeventd.o \
|
||||
-o $@ $(DL_LIBS) $(DMEVENT_LIBS) $(LIBS)
|
||||
$(Q) $(CC) $(CFLAGS) -L. $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) dmeventd.o \
|
||||
-o $@ $(DL_LIBS) $(DMEVENT_LIBS) $(LIBS) -lm
|
||||
|
||||
dmeventd.static: $(LIB_STATIC) dmeventd.o
|
||||
@echo " [CC] $@"
|
||||
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -static dmeventd.o \
|
||||
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -static -L. -L$(interfacebuilddir) dmeventd.o \
|
||||
-o $@ $(DL_LIBS) $(DMEVENT_LIBS) $(LIBS) $(STATIC_LIBS)
|
||||
|
||||
ifeq ("@PKGCONFIG@", "yes")
|
||||
INSTALL_LIB_TARGETS += install_pkgconfig
|
||||
endif
|
||||
|
||||
ifneq ("$(CFLOW_CMD)", "")
|
||||
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
|
||||
-include $(top_builddir)/lib/liblvm-internal.cflow
|
||||
-include $(top_builddir)/lib/liblvm2cmd.cflow
|
||||
-include $(top_builddir)/daemons/dmeventd/$(LIB_NAME).cflow
|
||||
-include $(top_builddir)/daemons/dmeventd/plugins/mirror/$(LIB_NAME)-lvm2mirror.cflow
|
||||
endif
|
||||
|
||||
install_include: $(srcdir)/libdevmapper-event.h
|
||||
@echo " [INSTALL] $(<F)"
|
||||
@echo " [INSTALL] $<"
|
||||
$(Q) $(INSTALL_DATA) -D $< $(includedir)/$(<F)
|
||||
|
||||
install_pkgconfig: libdevmapper-event.pc
|
||||
|
@@ -752,7 +752,7 @@ static void _exit_timeout(void *unused __attribute__((unused)))
|
||||
static void *_timeout_thread(void *unused __attribute__((unused)))
|
||||
{
|
||||
struct thread_status *thread;
|
||||
struct timespec timeout, real_time;
|
||||
struct timespec timeout;
|
||||
time_t curr_time;
|
||||
int ret;
|
||||
|
||||
@@ -763,16 +763,7 @@ static void *_timeout_thread(void *unused __attribute__((unused)))
|
||||
while (!dm_list_empty(&_timeout_registry)) {
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_nsec = 0;
|
||||
#ifndef HAVE_REALTIME
|
||||
curr_time = time(NULL);
|
||||
#else
|
||||
if (clock_gettime(CLOCK_REALTIME, &real_time)) {
|
||||
log_error("Failed to read clock_gettime().");
|
||||
break;
|
||||
}
|
||||
/* 10ms back to the future */
|
||||
curr_time = real_time.tv_sec + ((real_time.tv_nsec > (1000000000 - 10000000)) ? 1 : 0);
|
||||
#endif
|
||||
|
||||
dm_list_iterate_items_gen(thread, &_timeout_registry, timeout_list) {
|
||||
if (thread->next_time <= curr_time) {
|
||||
@@ -1494,34 +1485,37 @@ static int _client_read(struct dm_event_fifos *fifos,
|
||||
t.tv_usec = 0;
|
||||
ret = select(fifos->client + 1, &fds, NULL, NULL, &t);
|
||||
|
||||
if (!ret && bytes)
|
||||
continue; /* trying to finish read */
|
||||
if (!ret && !bytes) /* nothing to read */
|
||||
return 0;
|
||||
|
||||
if (ret <= 0) /* nothing to read */
|
||||
goto bad;
|
||||
if (!ret) /* trying to finish read */
|
||||
continue;
|
||||
|
||||
if (ret < 0) /* error */
|
||||
return 0;
|
||||
|
||||
ret = read(fifos->client, buf + bytes, size - bytes);
|
||||
bytes += ret > 0 ? ret : 0;
|
||||
if (!msg->data && (bytes == 2 * sizeof(uint32_t))) {
|
||||
if (header && (bytes == 2 * sizeof(uint32_t))) {
|
||||
msg->cmd = ntohl(header[0]);
|
||||
size = msg->size = ntohl(header[1]);
|
||||
bytes = 0;
|
||||
|
||||
if (!(size = msg->size = ntohl(header[1])))
|
||||
break;
|
||||
|
||||
if (!(buf = msg->data = malloc(msg->size)))
|
||||
goto bad;
|
||||
if (!size)
|
||||
break; /* No data -> error */
|
||||
buf = msg->data = malloc(msg->size);
|
||||
if (!buf)
|
||||
break; /* No mem -> error */
|
||||
header = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes == size)
|
||||
return 1;
|
||||
if (bytes != size) {
|
||||
free(msg->data);
|
||||
msg->data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bad:
|
||||
free(msg->data);
|
||||
msg->data = NULL;
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1751,8 +1745,7 @@ static void _init_thread_signals(void)
|
||||
sigdelset(&my_sigset, SIGHUP);
|
||||
sigdelset(&my_sigset, SIGQUIT);
|
||||
|
||||
if (pthread_sigmask(SIG_BLOCK, &my_sigset, NULL))
|
||||
log_sys_error("pthread_sigmask", "SIG_BLOCK");
|
||||
pthread_sigmask(SIG_BLOCK, &my_sigset, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2028,8 +2021,8 @@ static int _reinstate_registrations(struct dm_event_fifos *fifos)
|
||||
static void _restart_dmeventd(void)
|
||||
{
|
||||
struct dm_event_fifos fifos = {
|
||||
.client = -1,
|
||||
.server = -1,
|
||||
.client = -1,
|
||||
/* FIXME Make these either configurable or depend directly on dmeventd_path */
|
||||
.client_path = DM_EVENT_FIFO_CLIENT,
|
||||
.server_path = DM_EVENT_FIFO_SERVER
|
||||
@@ -2243,8 +2236,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
_init_thread_signals();
|
||||
|
||||
if (pthread_mutex_init(&_global_mutex, NULL))
|
||||
exit(EXIT_FAILURE);
|
||||
pthread_mutex_init(&_global_mutex, NULL);
|
||||
|
||||
if (!_systemd_activation && !_open_fifos(&fifos))
|
||||
exit(EXIT_FIFO_FAILURE);
|
||||
|
@@ -237,16 +237,16 @@ static int _daemon_read(struct dm_event_fifos *fifos,
|
||||
ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
|
||||
if (ret < 0 && errno != EINTR) {
|
||||
log_error("Unable to read from event server.");
|
||||
goto bad;
|
||||
return 0;
|
||||
}
|
||||
if ((ret == 0) && (i > 4) && !bytes) {
|
||||
log_error("No input from event server.");
|
||||
goto bad;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (ret < 1) {
|
||||
log_error("Unable to read from event server.");
|
||||
goto bad;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = read(fifos->server, buf + bytes, size);
|
||||
@@ -255,32 +255,25 @@ static int _daemon_read(struct dm_event_fifos *fifos,
|
||||
continue;
|
||||
|
||||
log_error("Unable to read from event server.");
|
||||
goto bad;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bytes += ret;
|
||||
if (!msg->data && (bytes == 2 * sizeof(uint32_t))) {
|
||||
if (header && (bytes == 2 * sizeof(uint32_t))) {
|
||||
msg->cmd = ntohl(header[0]);
|
||||
msg->size = ntohl(header[1]);
|
||||
buf = msg->data = malloc(msg->size);
|
||||
size = msg->size;
|
||||
bytes = 0;
|
||||
|
||||
if (!(size = msg->size = ntohl(header[1])))
|
||||
break;
|
||||
|
||||
if (!(buf = msg->data = malloc(msg->size))) {
|
||||
log_error("Unable to allocate message data.");
|
||||
return 0;
|
||||
}
|
||||
header = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes == size)
|
||||
return 1;
|
||||
|
||||
bad:
|
||||
free(msg->data);
|
||||
msg->data = NULL;
|
||||
|
||||
return 0;
|
||||
if (bytes != size) {
|
||||
free(msg->data);
|
||||
msg->data = NULL;
|
||||
}
|
||||
return bytes == size;
|
||||
}
|
||||
|
||||
/* Write message to daemon. */
|
||||
@@ -615,8 +608,8 @@ static int _do_event(int cmd, char *dmeventd_path, struct dm_event_daemon_messag
|
||||
{
|
||||
int ret;
|
||||
struct dm_event_fifos fifos = {
|
||||
.client = -1,
|
||||
.server = -1,
|
||||
.client = -1,
|
||||
/* FIXME Make these either configurable or depend directly on dmeventd_path */
|
||||
.client_path = DM_EVENT_FIFO_CLIENT,
|
||||
.server_path = DM_EVENT_FIFO_SERVER
|
||||
|
@@ -71,7 +71,7 @@ int dmeventd_lvm2_init(void)
|
||||
if (!_lvm_handle) {
|
||||
lvm2_log_fn(_lvm2_print_log);
|
||||
|
||||
if (!(_lvm_handle = lvm2_init_threaded()))
|
||||
if (!(_lvm_handle = lvm2_init()))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
|
@@ -25,6 +25,9 @@ LIB_NAME = libdevmapper-event-lvm2mirror
|
||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
|
||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
||||
|
||||
CFLOW_LIST = $(SOURCES)
|
||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
|
||||
|
||||
include $(top_builddir)/make.tmpl
|
||||
|
||||
install_lvm2: install_dm_plugin
|
||||
|
@@ -24,6 +24,9 @@ LIB_NAME = libdevmapper-event-lvm2raid
|
||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
|
||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
||||
|
||||
CFLOW_LIST = $(SOURCES)
|
||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
|
||||
|
||||
include $(top_builddir)/make.tmpl
|
||||
|
||||
install_lvm2: install_dm_plugin
|
||||
|
@@ -77,7 +77,7 @@ static int _process_raid_event(struct dso_state *state, char *params, const char
|
||||
|
||||
if (dead) {
|
||||
/*
|
||||
* Use the first event to run a repair ignoring any additional ones.
|
||||
* Use the first event to run a repair ignoring any additonal ones.
|
||||
*
|
||||
* We presume lvconvert to do pre-repair
|
||||
* checks to avoid bloat in this plugin.
|
||||
|
@@ -24,6 +24,9 @@ LIB_NAME = libdevmapper-event-lvm2thin
|
||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
|
||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
||||
|
||||
CFLOW_LIST = $(SOURCES)
|
||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
|
||||
|
||||
include $(top_builddir)/make.tmpl
|
||||
|
||||
install_lvm2: install_dm_plugin
|
||||
|
@@ -24,6 +24,9 @@ LIB_NAME = libdevmapper-event-lvm2vdo
|
||||
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
|
||||
LIB_VERSION = $(LIB_VERSION_LVM)
|
||||
|
||||
CFLOW_LIST = $(SOURCES)
|
||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
|
||||
|
||||
include $(top_builddir)/make.tmpl
|
||||
|
||||
install_lvm2: install_dm_plugin
|
||||
|
@@ -16,12 +16,7 @@
|
||||
#include "daemons/dmeventd/plugins/lvm2/dmeventd_lvm.h"
|
||||
#include "daemons/dmeventd/libdevmapper-event.h"
|
||||
|
||||
/*
|
||||
* Use parser from new device_mapper library.
|
||||
* Although during compilation we can see dm_vdo_status_parse()
|
||||
* in runtime we are linked agains systems libdm 'older' library
|
||||
* which does not provide this symbol and plugin fails to load
|
||||
*/
|
||||
/* Use parser from new device_mapper library */
|
||||
#include "device_mapper/vdo/status.c"
|
||||
|
||||
#include <sys/wait.h>
|
||||
|
@@ -15,8 +15,7 @@ srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
top_builddir = @top_builddir@
|
||||
|
||||
lvmdbuspydir = $(python3dir)/lvmdbusd
|
||||
lvmdbusdir = $(DESTDIR)$(lvmdbuspydir)
|
||||
lvmdbusdir = $(python3dir)/lvmdbusd
|
||||
|
||||
LVMDBUS_SRCDIR_FILES = \
|
||||
automatedproperties.py \
|
||||
@@ -54,16 +53,16 @@ include $(top_builddir)/make.tmpl
|
||||
all:
|
||||
$(Q) test -x $(LVMDBUSD) || chmod 755 $(LVMDBUSD)
|
||||
|
||||
install_lvmdbusd: $(LVMDBUSD)
|
||||
install_lvmdbusd:
|
||||
@echo " [INSTALL] $<"
|
||||
$(Q) $(INSTALL_DIR) $(sbindir)
|
||||
$(Q) $(INSTALL_SCRIPT) $(LVMDBUSD) $(sbindir)
|
||||
$(Q) $(INSTALL_DIR) $(lvmdbusdir)
|
||||
$(Q) (cd $(srcdir); $(INSTALL_DATA) $(LVMDBUS_SRCDIR_FILES) $(lvmdbusdir))
|
||||
$(Q) $(INSTALL_DATA) $(LVMDBUS_BUILDDIR_FILES) $(lvmdbusdir)
|
||||
$(Q) PYTHON=$(PYTHON3) $(PYCOMPILE) --destdir "$(DESTDIR)" --basedir "$(lvmdbuspydir)" $(LVMDBUS_SRCDIR_FILES) $(LVMDBUS_BUILDDIR_FILES)
|
||||
$(Q) $(CHMOD) 755 $(lvmdbusdir)/__pycache__
|
||||
$(Q) $(CHMOD) 444 $(lvmdbusdir)/__pycache__/*.py[co]
|
||||
$(Q) $(INSTALL_DIR) $(DESTDIR)$(lvmdbusdir)
|
||||
$(Q) (cd $(srcdir); $(INSTALL_DATA) $(LVMDBUS_SRCDIR_FILES) $(DESTDIR)$(lvmdbusdir))
|
||||
$(Q) $(INSTALL_DATA) $(LVMDBUS_BUILDDIR_FILES) $(DESTDIR)$(lvmdbusdir)
|
||||
$(Q) PYTHON=$(PYTHON3) $(PYCOMPILE) --destdir "$(DESTDIR)" --basedir "$(lvmdbusdir)" $(LVMDBUS_SRCDIR_FILES) $(LVMDBUS_BUILDDIR_FILES)
|
||||
$(Q) $(CHMOD) 755 $(DESTDIR)$(lvmdbusdir)/__pycache__
|
||||
$(Q) $(CHMOD) 444 $(DESTDIR)$(lvmdbusdir)/__pycache__/*.py[co]
|
||||
|
||||
install_lvm2: install_lvmdbusd
|
||||
|
||||
|
@@ -398,14 +398,6 @@ def vg_create_vdo_pool_lv_and_lv(vg_name, pool_name, lv_name, data_size,
|
||||
return call(cmd)
|
||||
|
||||
|
||||
def vg_create_vdo_pool(pool_full_name, lv_name, virtual_size, create_options):
|
||||
cmd = ['lvconvert']
|
||||
cmd.extend(options_to_cli_args(create_options))
|
||||
cmd.extend(['--type', 'vdo-pool', '-n', lv_name, '--force', '-y',
|
||||
'-V', '%dB' % virtual_size, pool_full_name])
|
||||
return call(cmd)
|
||||
|
||||
|
||||
def lv_remove(lv_path, remove_options):
|
||||
cmd = ['lvremove']
|
||||
cmd.extend(options_to_cli_args(remove_options))
|
||||
@@ -453,15 +445,6 @@ def lv_cache_lv(cache_pool_full_name, lv_full_name, cache_options):
|
||||
return call(cmd)
|
||||
|
||||
|
||||
def lv_writecache_lv(cache_lv_full_name, lv_full_name, cache_options):
|
||||
# lvconvert --type writecache --cachevol VG/CacheLV VG/OriginLV
|
||||
cmd = ['lvconvert']
|
||||
cmd.extend(options_to_cli_args(cache_options))
|
||||
cmd.extend(['-y', '--type', 'writecache', '--cachevol',
|
||||
cache_lv_full_name, lv_full_name])
|
||||
return call(cmd)
|
||||
|
||||
|
||||
def lv_detach_cache(lv_full_name, detach_options, destroy_cache):
|
||||
cmd = ['lvconvert']
|
||||
if destroy_cache:
|
||||
@@ -477,28 +460,6 @@ def lv_detach_cache(lv_full_name, detach_options, destroy_cache):
|
||||
return call(cmd)
|
||||
|
||||
|
||||
def lv_vdo_compression(lv_path, enable, comp_options):
|
||||
cmd = ['lvchange', '--compression']
|
||||
if enable:
|
||||
cmd.append('y')
|
||||
else:
|
||||
cmd.append('n')
|
||||
cmd.extend(options_to_cli_args(comp_options))
|
||||
cmd.append(lv_path)
|
||||
return call(cmd)
|
||||
|
||||
|
||||
def lv_vdo_deduplication(lv_path, enable, dedup_options):
|
||||
cmd = ['lvchange', '--deduplication']
|
||||
if enable:
|
||||
cmd.append('y')
|
||||
else:
|
||||
cmd.append('n')
|
||||
cmd.extend(options_to_cli_args(dedup_options))
|
||||
cmd.append(lv_path)
|
||||
return call(cmd)
|
||||
|
||||
|
||||
def supports_json():
|
||||
cmd = ['help']
|
||||
rc, out, err = call(cmd)
|
||||
|
@@ -388,7 +388,7 @@ class LvCommon(AutomatedProperties):
|
||||
'l': 'mirror log device', 'c': 'under conversion',
|
||||
'V': 'thin Volume', 't': 'thin pool', 'T': 'Thin pool data',
|
||||
'e': 'raid or pool metadata or pool metadata spare',
|
||||
'd': 'vdo pool', 'D': 'vdo pool data', 'g': 'integrity',
|
||||
'd': 'vdo pool', 'D': 'vdo pool data',
|
||||
'-': 'Unspecified'}
|
||||
return self.attr_struct(0, type_map)
|
||||
|
||||
@@ -743,49 +743,6 @@ class Lv(LvCommon):
|
||||
cb, cbe, return_tuple=False)
|
||||
cfg.worker_q.put(r)
|
||||
|
||||
@staticmethod
|
||||
def _writecache_lv(lv_uuid, lv_name, lv_object_path, cache_options):
|
||||
# Make sure we have a dbus object representing it
|
||||
dbo = LvCommon.validate_dbus_object(lv_uuid, lv_name)
|
||||
|
||||
# Make sure we have dbus object representing lv to cache
|
||||
lv_to_cache = cfg.om.get_object_by_path(lv_object_path)
|
||||
|
||||
if lv_to_cache:
|
||||
fcn = lv_to_cache.lv_full_name()
|
||||
rc, out, err = cmdhandler.lv_writecache_lv(
|
||||
dbo.lv_full_name(), fcn, cache_options)
|
||||
if rc == 0:
|
||||
# When we cache an LV, the cache pool and the lv that is getting
|
||||
# cached need to be removed from the object manager and
|
||||
# re-created as their interfaces have changed!
|
||||
mt_remove_dbus_objects((dbo, lv_to_cache))
|
||||
cfg.load()
|
||||
|
||||
lv_converted = cfg.om.get_object_path_by_lvm_id(fcn)
|
||||
else:
|
||||
raise dbus.exceptions.DBusException(
|
||||
LV_INTERFACE,
|
||||
'Exit code %s, stderr = %s' % (str(rc), err))
|
||||
else:
|
||||
raise dbus.exceptions.DBusException(
|
||||
LV_INTERFACE, 'LV to cache with object path %s not present!' %
|
||||
lv_object_path)
|
||||
return lv_converted
|
||||
|
||||
@dbus.service.method(
|
||||
dbus_interface=LV_INTERFACE,
|
||||
in_signature='oia{sv}',
|
||||
out_signature='(oo)',
|
||||
async_callbacks=('cb', 'cbe'))
|
||||
def WriteCacheLv(self, lv_object, tmo, cache_options, cb, cbe):
|
||||
r = RequestEntry(
|
||||
tmo, Lv._writecache_lv,
|
||||
(self.Uuid, self.lvm_id, lv_object,
|
||||
cache_options), cb, cbe)
|
||||
cfg.worker_q.put(r)
|
||||
|
||||
|
||||
# noinspection PyPep8Naming
|
||||
@utils.dbus_property(VDO_POOL_INTERFACE, 'OperatingMode', 's')
|
||||
@utils.dbus_property(VDO_POOL_INTERFACE, 'CompressionState', 's')
|
||||
@@ -823,72 +780,6 @@ class LvVdoPool(Lv):
|
||||
def DataLv(self):
|
||||
return dbus.ObjectPath(self._data_lv)
|
||||
|
||||
@staticmethod
|
||||
def _enable_disable_compression(pool_uuid, pool_name, enable, comp_options):
|
||||
# Make sure we have a dbus object representing it
|
||||
LvCommon.validate_dbus_object(pool_uuid, pool_name)
|
||||
# Rename the logical volume
|
||||
LvCommon.handle_execute(*cmdhandler.lv_vdo_compression(
|
||||
pool_name, enable, comp_options))
|
||||
return '/'
|
||||
|
||||
@dbus.service.method(
|
||||
dbus_interface=VDO_POOL_INTERFACE,
|
||||
in_signature='ia{sv}',
|
||||
out_signature='o',
|
||||
async_callbacks=('cb', 'cbe'))
|
||||
def EnableCompression(self, tmo, comp_options, cb, cbe):
|
||||
r = RequestEntry(
|
||||
tmo, LvVdoPool._enable_disable_compression,
|
||||
(self.Uuid, self.lvm_id, True, comp_options),
|
||||
cb, cbe, False)
|
||||
cfg.worker_q.put(r)
|
||||
|
||||
@dbus.service.method(
|
||||
dbus_interface=VDO_POOL_INTERFACE,
|
||||
in_signature='ia{sv}',
|
||||
out_signature='o',
|
||||
async_callbacks=('cb', 'cbe'))
|
||||
def DisableCompression(self, tmo, comp_options, cb, cbe):
|
||||
r = RequestEntry(
|
||||
tmo, LvVdoPool._enable_disable_compression,
|
||||
(self.Uuid, self.lvm_id, False, comp_options),
|
||||
cb, cbe, False)
|
||||
cfg.worker_q.put(r)
|
||||
|
||||
@staticmethod
|
||||
def _enable_disable_deduplication(pool_uuid, pool_name, enable, dedup_options):
|
||||
# Make sure we have a dbus object representing it
|
||||
LvCommon.validate_dbus_object(pool_uuid, pool_name)
|
||||
# Rename the logical volume
|
||||
LvCommon.handle_execute(*cmdhandler.lv_vdo_deduplication(
|
||||
pool_name, enable, dedup_options))
|
||||
return '/'
|
||||
|
||||
@dbus.service.method(
|
||||
dbus_interface=VDO_POOL_INTERFACE,
|
||||
in_signature='ia{sv}',
|
||||
out_signature='o',
|
||||
async_callbacks=('cb', 'cbe'))
|
||||
def EnableDeduplication(self, tmo, dedup_options, cb, cbe):
|
||||
r = RequestEntry(
|
||||
tmo, LvVdoPool._enable_disable_deduplication,
|
||||
(self.Uuid, self.lvm_id, True, dedup_options),
|
||||
cb, cbe, False)
|
||||
cfg.worker_q.put(r)
|
||||
|
||||
@dbus.service.method(
|
||||
dbus_interface=VDO_POOL_INTERFACE,
|
||||
in_signature='ia{sv}',
|
||||
out_signature='o',
|
||||
async_callbacks=('cb', 'cbe'))
|
||||
def DisableDeduplication(self, tmo, dedup_options, cb, cbe):
|
||||
r = RequestEntry(
|
||||
tmo, LvVdoPool._enable_disable_deduplication,
|
||||
(self.Uuid, self.lvm_id, False, dedup_options),
|
||||
cb, cbe, False)
|
||||
cfg.worker_q.put(r)
|
||||
|
||||
|
||||
# noinspection PyPep8Naming
|
||||
class LvThinPool(Lv):
|
||||
|
@@ -27,7 +27,7 @@ class Manager(AutomatedProperties):
|
||||
|
||||
@property
|
||||
def Version(self):
|
||||
return dbus.String('1.1.0')
|
||||
return dbus.String('1.0.0')
|
||||
|
||||
@staticmethod
|
||||
def handle_execute(rc, out, err):
|
||||
|
@@ -813,35 +813,3 @@ class VgVdo(Vg):
|
||||
round_size(virtual_size),
|
||||
create_options), cb, cbe)
|
||||
cfg.worker_q.put(r)
|
||||
|
||||
@staticmethod
|
||||
def _vdo_pool_create(uuid, vg_name, pool_lv, name, virtual_size, create_options):
|
||||
Vg.validate_dbus_object(uuid, vg_name)
|
||||
|
||||
# Retrieve the full name of the pool lv
|
||||
pool = cfg.om.get_object_by_path(pool_lv)
|
||||
if not pool:
|
||||
msg = 'LV with object path %s not present!' % \
|
||||
(pool_lv)
|
||||
raise dbus.exceptions.DBusException(VG_VDO_INTERFACE, msg)
|
||||
|
||||
Vg.handle_execute(*cmdhandler.vg_create_vdo_pool(
|
||||
pool.lv_full_name(), name, virtual_size,
|
||||
create_options))
|
||||
return Vg.fetch_new_lv(vg_name, pool.Name)
|
||||
|
||||
@dbus.service.method(
|
||||
dbus_interface=VG_VDO_INTERFACE,
|
||||
in_signature='ostia{sv}',
|
||||
out_signature='(oo)',
|
||||
async_callbacks=('cb', 'cbe'))
|
||||
def CreateVdoPool(self, pool_lv, name, virtual_size,
|
||||
tmo, create_options, cb, cbe):
|
||||
utils.validate_lv_name(VG_VDO_INTERFACE, self.Name, name)
|
||||
|
||||
r = RequestEntry(tmo, VgVdo._vdo_pool_create,
|
||||
(self.state.Uuid, self.state.lvm_id,
|
||||
pool_lv, name,
|
||||
round_size(virtual_size),
|
||||
create_options), cb, cbe)
|
||||
cfg.worker_q.put(r)
|
||||
|
@@ -34,30 +34,29 @@ SOURCES2 = lvmlockctl.c
|
||||
|
||||
TARGETS = lvmlockd lvmlockctl
|
||||
|
||||
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
|
||||
CFLOW_TARGET = lvmlockd
|
||||
|
||||
.PHONY: install_lvmlockd install_lvmlockctl
|
||||
.PHONY: install_lvmlockd
|
||||
|
||||
include $(top_builddir)/make.tmpl
|
||||
|
||||
CFLAGS += $(EXTRA_EXEC_CFLAGS)
|
||||
INCLUDES += -I$(top_srcdir)/libdaemon/server
|
||||
LDFLAGS += -L$(top_builddir)/libdaemon/server $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
|
||||
LIBS += $(DAEMON_LIBS) $(PTHREAD_LIBS)
|
||||
LIBS += $(RT_LIBS) $(DAEMON_LIBS) $(PTHREAD_LIBS)
|
||||
|
||||
|
||||
ifeq ($(USE_SD_NOTIFY),yes)
|
||||
CFLAGS += $(shell pkg-config --cflags libsystemd) -DUSE_SD_NOTIFY
|
||||
LIBS += $(shell pkg-config --libs libsystemd)
|
||||
endif
|
||||
|
||||
lvmlockd: $(OBJECTS) $(top_builddir)/libdaemon/server/libdaemonserver.a $(INTERNAL_LIBS)
|
||||
lvmlockd: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
|
||||
$(top_builddir)/libdaemon/server/libdaemonserver.a
|
||||
@echo " [CC] $@"
|
||||
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ $(LOCK_LIBS) $(LIBS)
|
||||
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LOCK_LIBS) -ldaemonserver $(INTERNAL_LIBS) $(LIBS)
|
||||
|
||||
lvmlockctl: lvmlockctl.o $(INTERNAL_LIBS)
|
||||
lvmlockctl: lvmlockctl.o $(top_builddir)/libdaemon/client/libdaemonclient.a
|
||||
@echo " [CC] $@"
|
||||
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS)
|
||||
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ lvmlockctl.o $(INTERNAL_LIBS) $(LIBS)
|
||||
|
||||
install_lvmlockd: lvmlockd
|
||||
@echo " [INSTALL] $<"
|
||||
|
@@ -18,11 +18,8 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <syslog.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
static int quit = 0;
|
||||
static int info = 0;
|
||||
@@ -33,7 +30,6 @@ static int kill_vg = 0;
|
||||
static int drop_vg = 0;
|
||||
static int gl_enable = 0;
|
||||
static int gl_disable = 0;
|
||||
static int use_stderr = 0;
|
||||
static int stop_lockspaces = 0;
|
||||
static char *arg_vg_name = NULL;
|
||||
|
||||
@@ -51,22 +47,6 @@ do { \
|
||||
printf(fmt "\n", ##args); \
|
||||
} while (0)
|
||||
|
||||
#define log_sys_emerg(fmt, args...) \
|
||||
do { \
|
||||
if (use_stderr) \
|
||||
fprintf(stderr, fmt "\n", ##args); \
|
||||
else \
|
||||
syslog(LOG_EMERG, fmt, ##args); \
|
||||
} while (0)
|
||||
|
||||
#define log_sys_warn(fmt, args...) \
|
||||
do { \
|
||||
if (use_stderr) \
|
||||
fprintf(stderr, fmt "\n", ##args); \
|
||||
else \
|
||||
syslog(LOG_WARNING, fmt, ##args); \
|
||||
} while (0)
|
||||
|
||||
#define MAX_LINE 512
|
||||
|
||||
/* copied from lvmlockd-internal.h */
|
||||
@@ -300,12 +280,13 @@ static void format_info_line(char *line, char *r_name, char *r_type)
|
||||
|
||||
static void format_info(void)
|
||||
{
|
||||
char line[MAX_LINE] = { 0 };
|
||||
char r_name[MAX_NAME+1] = { 0 };
|
||||
char r_type[MAX_NAME+1] = { 0 };
|
||||
char line[MAX_LINE];
|
||||
char r_name[MAX_NAME+1];
|
||||
char r_type[MAX_NAME+1];
|
||||
int i, j;
|
||||
|
||||
j = 0;
|
||||
memset(line, 0, sizeof(line));
|
||||
|
||||
for (i = 0; i < dump_len; i++) {
|
||||
line[j++] = dump_buf[i];
|
||||
@@ -345,8 +326,6 @@ static int _lvmlockd_result(daemon_reply reply, int *result)
|
||||
{
|
||||
int reply_result;
|
||||
|
||||
*result = NO_LOCKD_RESULT;
|
||||
|
||||
if (reply.error) {
|
||||
log_error("lvmlockd_result reply error %d", reply.error);
|
||||
return 0;
|
||||
@@ -358,7 +337,7 @@ static int _lvmlockd_result(daemon_reply reply, int *result)
|
||||
}
|
||||
|
||||
reply_result = daemon_reply_int(reply, "op_result", NO_LOCKD_RESULT);
|
||||
if (reply_result == NO_LOCKD_RESULT) {
|
||||
if (reply_result == -1000) {
|
||||
log_error("lvmlockd_result no op_result");
|
||||
return 0;
|
||||
}
|
||||
@@ -522,274 +501,51 @@ static int do_stop_lockspaces(void)
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int _reopen_fd_to_null(int fd)
|
||||
static int do_kill(void)
|
||||
{
|
||||
int null_fd;
|
||||
int r = 0;
|
||||
|
||||
if ((null_fd = open("/dev/null", O_RDWR)) == -1) {
|
||||
log_error("open error /dev/null %d", errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (close(fd)) {
|
||||
log_error("close error fd %d %d", fd, errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dup2(null_fd, fd) == -1) {
|
||||
log_error("dup2 error %d", errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = 1;
|
||||
out:
|
||||
if (close(null_fd)) {
|
||||
log_error("close error fd %d %d", null_fd, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#define MAX_AV_COUNT 32
|
||||
#define ONE_ARG_LEN 1024
|
||||
|
||||
static void _run_command_pipe(const char *cmd_str, pid_t *pid_out, FILE **fp_out)
|
||||
{
|
||||
char arg[ONE_ARG_LEN];
|
||||
char *av[MAX_AV_COUNT + 1]; /* +1 for NULL */
|
||||
char *arg_dup;
|
||||
int av_count = 0;
|
||||
int cmd_len;
|
||||
int arg_len;
|
||||
pid_t pid = 0;
|
||||
FILE *fp = NULL;
|
||||
int pipefd[2];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_AV_COUNT + 1; i++)
|
||||
av[i] = NULL;
|
||||
|
||||
cmd_len = strlen(cmd_str);
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
arg_len = 0;
|
||||
|
||||
for (i = 0; i < cmd_len; i++) {
|
||||
if (!cmd_str[i])
|
||||
break;
|
||||
|
||||
if (av_count == MAX_AV_COUNT)
|
||||
goto out;
|
||||
|
||||
if (cmd_str[i] == '\\') {
|
||||
if (i == (cmd_len - 1))
|
||||
break;
|
||||
i++;
|
||||
|
||||
if (cmd_str[i] == '\\') {
|
||||
arg[arg_len++] = cmd_str[i];
|
||||
continue;
|
||||
}
|
||||
if (isspace(cmd_str[i])) {
|
||||
arg[arg_len++] = cmd_str[i];
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isalnum(cmd_str[i]) || ispunct(cmd_str[i])) {
|
||||
arg[arg_len++] = cmd_str[i];
|
||||
} else if (isspace(cmd_str[i])) {
|
||||
if (arg_len) {
|
||||
if (!(arg_dup = strdup(arg)))
|
||||
goto out;
|
||||
av[av_count++] = arg_dup;
|
||||
}
|
||||
|
||||
memset(arg, 0, sizeof(arg));
|
||||
arg_len = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (arg_len) {
|
||||
if (av_count >= MAX_AV_COUNT)
|
||||
goto out;
|
||||
if (!(arg_dup = strdup(arg)))
|
||||
goto out;
|
||||
av[av_count++] = arg_dup;
|
||||
}
|
||||
|
||||
if (pipe(pipefd)) {
|
||||
log_error("pipe error %d", errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (pid < 0) {
|
||||
log_error("fork error %d", errno);
|
||||
pid = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
/* Child -> writer, convert pipe[0] to STDOUT */
|
||||
if (!_reopen_fd_to_null(STDIN_FILENO))
|
||||
log_error("reopen STDIN error");
|
||||
else if (close(pipefd[0 /*read*/]))
|
||||
log_error("close error pipe[0] %d", errno);
|
||||
else if (close(STDOUT_FILENO))
|
||||
log_error("close error STDOUT %d", errno);
|
||||
else if (dup2(pipefd[1 /*write*/], STDOUT_FILENO) == -1)
|
||||
log_error("dup2 error STDOUT %d", errno);
|
||||
else if (close(pipefd[1]))
|
||||
log_error("close error pipe[1] %d", errno);
|
||||
else {
|
||||
execvp(av[0], av);
|
||||
log_error("execvp error %d", errno);
|
||||
}
|
||||
_exit(errno);
|
||||
}
|
||||
|
||||
/* Parent -> reader */
|
||||
if (close(pipefd[1 /*write*/]))
|
||||
log_error("close error STDOUT %d", errno);
|
||||
|
||||
if (!(fp = fdopen(pipefd[0 /*read*/], "r"))) {
|
||||
log_error("fdopen STDIN error %d", errno);
|
||||
if (close(pipefd[0]))
|
||||
log_error("close error STDIN %d", errno);
|
||||
}
|
||||
|
||||
out:
|
||||
for (i = 0; i < MAX_AV_COUNT + 1; i++)
|
||||
free(av[i]);
|
||||
|
||||
*pid_out = pid;
|
||||
*fp_out = fp;
|
||||
}
|
||||
|
||||
/* Returns -1 on error, 0 on success. */
|
||||
|
||||
static int _close_command_pipe(pid_t pid, FILE *fp)
|
||||
{
|
||||
int status, estatus;
|
||||
int ret = -1;
|
||||
|
||||
if (waitpid(pid, &status, 0) != pid) {
|
||||
log_error("waitpid error pid %d %d", pid, errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
/* pid exited with an exit code */
|
||||
estatus = WEXITSTATUS(status);
|
||||
|
||||
/* exit status 0: child success */
|
||||
if (!estatus) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* exit status not zero: child error */
|
||||
log_error("child exit error %d", estatus);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (WIFSIGNALED(status)) {
|
||||
/* pid terminated due to a signal */
|
||||
log_error("child exit from signal");
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_error("child exit problem");
|
||||
|
||||
out:
|
||||
if (fp && fclose(fp))
|
||||
log_error("fclose error STDIN %d", errno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Returns -1 on error, 0 on success. */
|
||||
|
||||
static int _get_kill_command(char *kill_cmd)
|
||||
{
|
||||
char config_cmd[PATH_MAX + 128] = { 0 };
|
||||
char config_val[1024] = { 0 };
|
||||
char line[PATH_MAX] = { 0 };
|
||||
pid_t pid = 0;
|
||||
FILE *fp = NULL;
|
||||
|
||||
snprintf(config_cmd, PATH_MAX, "%s config --typeconfig full global/lvmlockctl_kill_command", LVM_PATH);
|
||||
|
||||
_run_command_pipe(config_cmd, &pid, &fp);
|
||||
|
||||
if (!pid) {
|
||||
log_error("failed to run %s", config_cmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!fp) {
|
||||
log_error("failed to get output %s", config_cmd);
|
||||
_close_command_pipe(pid, fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!fgets(line, sizeof(line), fp)) {
|
||||
log_error("no output from %s", config_cmd);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (sscanf(line, "lvmlockctl_kill_command=\"%256[^\n\"]\"", config_val) != 1) {
|
||||
log_error("unrecognized config value from %s", config_cmd);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!config_val[0] || (config_val[0] == ' ')) {
|
||||
log_error("invalid config value from %s", config_cmd);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (config_val[0] != '/') {
|
||||
log_error("lvmlockctl_kill_command must be full path");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
printf("Found lvmlockctl_kill_command: %s\n", config_val);
|
||||
|
||||
snprintf(kill_cmd, PATH_MAX, "%s %s", config_val, arg_vg_name);
|
||||
kill_cmd[PATH_MAX-1] = '\0';
|
||||
|
||||
_close_command_pipe(pid, fp);
|
||||
return 0;
|
||||
bad:
|
||||
_close_command_pipe(pid, fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns -1 on error, 0 on success. */
|
||||
|
||||
static int _run_kill_command(char *kill_cmd)
|
||||
{
|
||||
pid_t pid = 0;
|
||||
FILE *fp = NULL;
|
||||
daemon_reply reply;
|
||||
int result;
|
||||
int rv;
|
||||
|
||||
_run_command_pipe(kill_cmd, &pid, &fp);
|
||||
rv = _close_command_pipe(pid, fp);
|
||||
syslog(LOG_EMERG, "Lost access to sanlock lease storage in VG %s.", arg_vg_name);
|
||||
/* These two lines explain the manual alternative to the FIXME below. */
|
||||
syslog(LOG_EMERG, "Immediately deactivate LVs in VG %s.", arg_vg_name);
|
||||
syslog(LOG_EMERG, "Once VG is unused, run lvmlockctl --drop %s.", arg_vg_name);
|
||||
|
||||
if (!pid)
|
||||
return -1;
|
||||
/*
|
||||
* It may not be strictly necessary to notify lvmlockd of the kill, but
|
||||
* lvmlockd can use this information to avoid attempting any new lock
|
||||
* requests in the VG (which would fail anyway), and can return an
|
||||
* error indicating that the VG has been killed.
|
||||
*/
|
||||
|
||||
if (rv < 0)
|
||||
return -1;
|
||||
reply = _lvmlockd_send("kill_vg",
|
||||
"cmd = %s", "lvmlockctl",
|
||||
"pid = " FMTd64, (int64_t) getpid(),
|
||||
"vg_name = %s", arg_vg_name,
|
||||
NULL);
|
||||
|
||||
return 0;
|
||||
if (!_lvmlockd_result(reply, &result)) {
|
||||
log_error("lvmlockd result %d", result);
|
||||
rv = result;
|
||||
} else {
|
||||
rv = 0;
|
||||
}
|
||||
|
||||
daemon_reply_destroy(reply);
|
||||
|
||||
/*
|
||||
* FIXME: here is where we should implement a strong form of
|
||||
* blkdeactivate, and if it completes successfully, automatically call
|
||||
* do_drop() afterward. (The drop step may not always be necessary
|
||||
* if the lvm commands run while shutting things down release all the
|
||||
* leases.)
|
||||
*
|
||||
* run_strong_blkdeactivate();
|
||||
* do_drop();
|
||||
*/
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int do_drop(void)
|
||||
@@ -798,7 +554,7 @@ static int do_drop(void)
|
||||
int result;
|
||||
int rv;
|
||||
|
||||
log_sys_warn("Dropping locks for VG %s.", arg_vg_name);
|
||||
syslog(LOG_WARNING, "Dropping locks for VG %s.", arg_vg_name);
|
||||
|
||||
/*
|
||||
* Check for misuse by looking for any active LVs in the VG
|
||||
@@ -826,84 +582,6 @@ static int do_drop(void)
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int do_kill(void)
|
||||
{
|
||||
char kill_cmd[PATH_MAX] = { 0 };
|
||||
daemon_reply reply;
|
||||
int no_kill_command = 0;
|
||||
int result;
|
||||
int rv;
|
||||
|
||||
log_sys_emerg("lvmlockd lost access to locks in VG %s.", arg_vg_name);
|
||||
|
||||
rv = _get_kill_command(kill_cmd);
|
||||
if (rv < 0) {
|
||||
log_sys_emerg("Immediately deactivate LVs in VG %s.", arg_vg_name);
|
||||
log_sys_emerg("Once VG is unused, run lvmlockctl --drop %s.", arg_vg_name);
|
||||
no_kill_command = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* It may not be strictly necessary to notify lvmlockd of the kill, but
|
||||
* lvmlockd can use this information to avoid attempting any new lock
|
||||
* requests in the VG (which would fail anyway), and can return an
|
||||
* error indicating that the VG has been killed.
|
||||
*/
|
||||
_lvmlockd = lvmlockd_open(NULL);
|
||||
if (_lvmlockd.socket_fd < 0 || _lvmlockd.error) {
|
||||
log_error("Cannot connect to lvmlockd for kill_vg.");
|
||||
goto run;
|
||||
}
|
||||
reply = _lvmlockd_send("kill_vg",
|
||||
"cmd = %s", "lvmlockctl",
|
||||
"pid = " FMTd64, (int64_t) getpid(),
|
||||
"vg_name = %s", arg_vg_name,
|
||||
NULL);
|
||||
if (!_lvmlockd_result(reply, &result))
|
||||
log_error("lvmlockd result %d kill_vg", result);
|
||||
daemon_reply_destroy(reply);
|
||||
lvmlockd_close(_lvmlockd);
|
||||
|
||||
run:
|
||||
if (no_kill_command)
|
||||
return 0;
|
||||
|
||||
rv = _run_kill_command(kill_cmd);
|
||||
if (rv < 0) {
|
||||
log_sys_emerg("Failed to run VG %s kill command %s", arg_vg_name, kill_cmd);
|
||||
log_sys_emerg("Immediately deactivate LVs in VG %s.", arg_vg_name);
|
||||
log_sys_emerg("Once VG is unused, run lvmlockctl --drop %s.", arg_vg_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
log_sys_warn("Successful VG %s kill command %s", arg_vg_name, kill_cmd);
|
||||
|
||||
/*
|
||||
* If kill command was successfully, call do_drop(). (The drop step
|
||||
* may not always be necessary if the lvm commands run while shutting
|
||||
* things down release all the leases.)
|
||||
*/
|
||||
rv = 0;
|
||||
_lvmlockd = lvmlockd_open(NULL);
|
||||
if (_lvmlockd.socket_fd < 0 || _lvmlockd.error) {
|
||||
log_sys_emerg("Failed to connect to lvmlockd to drop locks in VG %s.", arg_vg_name);
|
||||
return -1;
|
||||
}
|
||||
reply = _lvmlockd_send("drop_vg",
|
||||
"cmd = %s", "lvmlockctl",
|
||||
"pid = " FMTd64, (int64_t) getpid(),
|
||||
"vg_name = %s", arg_vg_name,
|
||||
NULL);
|
||||
if (!_lvmlockd_result(reply, &result)) {
|
||||
log_sys_emerg("Failed to drop locks in VG %s", arg_vg_name);
|
||||
rv = result;
|
||||
}
|
||||
daemon_reply_destroy(reply);
|
||||
lvmlockd_close(_lvmlockd);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void print_usage(void)
|
||||
{
|
||||
printf("lvmlockctl options\n");
|
||||
@@ -921,7 +599,7 @@ static void print_usage(void)
|
||||
printf("--force | -f 0|1>\n");
|
||||
printf(" Force option for other commands.\n");
|
||||
printf("--kill | -k <vgname>\n");
|
||||
printf(" Kill access to the VG locks are lost (see lvmlockctl_kill_command).\n");
|
||||
printf(" Kill access to the VG when sanlock cannot renew lease.\n");
|
||||
printf("--drop | -r <vgname>\n");
|
||||
printf(" Clear locks for the VG when it is unused after kill (-k).\n");
|
||||
printf("--gl-enable | -E <vgname>\n");
|
||||
@@ -930,8 +608,6 @@ static void print_usage(void)
|
||||
printf(" Tell lvmlockd to disable the global lock in a sanlock VG.\n");
|
||||
printf("--stop-lockspaces | -S\n");
|
||||
printf(" Stop all lockspaces.\n");
|
||||
printf("--stderr | -e\n");
|
||||
printf(" Send kill and drop messages to stderr instead of syslog\n");
|
||||
}
|
||||
|
||||
static int read_options(int argc, char *argv[])
|
||||
@@ -951,7 +627,6 @@ static int read_options(int argc, char *argv[])
|
||||
{"gl-enable", required_argument, 0, 'E' },
|
||||
{"gl-disable", required_argument, 0, 'D' },
|
||||
{"stop-lockspaces", no_argument, 0, 'S' },
|
||||
{"stderr", no_argument, 0, 'e' },
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -961,7 +636,7 @@ static int read_options(int argc, char *argv[])
|
||||
}
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "hqidE:D:w:k:r:Se", long_options, &option_index);
|
||||
c = getopt_long(argc, argv, "hqidE:D:w:k:r:S", long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
@@ -1004,9 +679,6 @@ static int read_options(int argc, char *argv[])
|
||||
case 'S':
|
||||
stop_lockspaces = 1;
|
||||
break;
|
||||
case 'e':
|
||||
use_stderr = 1;
|
||||
break;
|
||||
default:
|
||||
print_usage();
|
||||
exit(1);
|
||||
@@ -1025,12 +697,8 @@ int main(int argc, char **argv)
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
/* do_kill handles lvmlockd connections itself */
|
||||
if (kill_vg)
|
||||
return do_kill();
|
||||
|
||||
|
||||
_lvmlockd = lvmlockd_open(NULL);
|
||||
|
||||
if (_lvmlockd.socket_fd < 0 || _lvmlockd.error) {
|
||||
log_error("Cannot connect to lvmlockd.");
|
||||
return -1;
|
||||
@@ -1051,6 +719,11 @@ int main(int argc, char **argv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (kill_vg) {
|
||||
rv = do_kill();
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (drop_vg) {
|
||||
rv = do_drop();
|
||||
goto out;
|
||||
|
@@ -14,7 +14,6 @@
|
||||
#include "libdaemon/client/daemon-client.h"
|
||||
|
||||
#define LVMLOCKD_SOCKET DEFAULT_RUN_DIR "/lvmlockd.socket"
|
||||
#define LVMLOCKD_ADOPT_FILE DEFAULT_RUN_DIR "/lvmlockd.adopt"
|
||||
|
||||
/* Wrappers to open/close connection */
|
||||
|
||||
@@ -23,9 +22,9 @@ static inline daemon_handle lvmlockd_open(const char *sock)
|
||||
daemon_info lvmlockd_info = {
|
||||
.path = "lvmlockd",
|
||||
.socket = sock ?: LVMLOCKD_SOCKET,
|
||||
.autostart = 0,
|
||||
.protocol = "lvmlockd",
|
||||
.protocol_version = 1,
|
||||
.autostart = 0
|
||||
};
|
||||
|
||||
return daemon_open(lvmlockd_info);
|
||||
@@ -33,7 +32,7 @@ static inline daemon_handle lvmlockd_open(const char *sock)
|
||||
|
||||
static inline void lvmlockd_close(daemon_handle h)
|
||||
{
|
||||
daemon_close(h);
|
||||
return daemon_close(h);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -38,8 +38,6 @@
|
||||
#define EXTERN
|
||||
#include "lvmlockd-internal.h"
|
||||
|
||||
static int str_to_mode(const char *str);
|
||||
|
||||
/*
|
||||
* Basic operation of lvmlockd
|
||||
*
|
||||
@@ -144,8 +142,6 @@ static const char *lvmlockd_protocol = "lvmlockd";
|
||||
static const int lvmlockd_protocol_version = 1;
|
||||
static int daemon_quit;
|
||||
static int adopt_opt;
|
||||
static uint32_t adopt_update_count;
|
||||
static const char *adopt_file;
|
||||
|
||||
/*
|
||||
* We use a separate socket for dumping daemon info.
|
||||
@@ -815,146 +811,6 @@ int version_from_args(char *args, unsigned int *major, unsigned int *minor, unsi
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write new info when a command exits if that command has acquired a new LV
|
||||
* lock. If the command has released an LV lock we don't bother updating the
|
||||
* info. When adopting, we eliminate any LV lock adoptions if there is no dm
|
||||
* device for that LV. If lvmlockd is terminated after acquiring but before
|
||||
* writing this file, those LV locks would not be adopted on restart.
|
||||
*/
|
||||
|
||||
#define ADOPT_VERSION_MAJOR 1
|
||||
#define ADOPT_VERSION_MINOR 0
|
||||
|
||||
static void write_adopt_file(void)
|
||||
{
|
||||
struct lockspace *ls;
|
||||
struct resource *r;
|
||||
struct lock *lk;
|
||||
time_t t;
|
||||
FILE *fp;
|
||||
|
||||
if (!(fp = fopen(adopt_file, "w")))
|
||||
return;
|
||||
|
||||
adopt_update_count++;
|
||||
|
||||
t = time(NULL);
|
||||
fprintf(fp, "lvmlockd adopt_version %u.%u pid %d updates %u %s",
|
||||
ADOPT_VERSION_MAJOR, ADOPT_VERSION_MINOR, getpid(), adopt_update_count, ctime(&t));
|
||||
|
||||
pthread_mutex_lock(&lockspaces_mutex);
|
||||
list_for_each_entry(ls, &lockspaces, list) {
|
||||
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
|
||||
continue;
|
||||
fprintf(fp, "VG: %38s %s %s %s\n",
|
||||
ls->vg_uuid, ls->vg_name, lm_str(ls->lm_type), ls->vg_args);
|
||||
list_for_each_entry(r, &ls->resources, list) {
|
||||
if (r->type != LD_RT_LV)
|
||||
continue;
|
||||
if ((r->mode != LD_LK_EX) && (r->mode != LD_LK_SH))
|
||||
continue;
|
||||
list_for_each_entry(lk, &r->locks, list) {
|
||||
fprintf(fp, "LV: %38s %s %s %s %u\n",
|
||||
ls->vg_uuid, r->name, r->lv_args, mode_str(r->mode), r->version);
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&lockspaces_mutex);
|
||||
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static int read_adopt_file(struct list_head *vg_lockd)
|
||||
{
|
||||
char adopt_line[512];
|
||||
char vg_uuid[72];
|
||||
char lm_type_str[16];
|
||||
char mode[8];
|
||||
struct lockspace *ls = NULL, *ls2;
|
||||
struct resource *r;
|
||||
FILE *fp;
|
||||
|
||||
if (MAX_ARGS != 64 || MAX_NAME != 64)
|
||||
return -1;
|
||||
|
||||
if (!(fp = fopen(adopt_file, "r")))
|
||||
return 0;
|
||||
|
||||
while (fgets(adopt_line, sizeof(adopt_line), fp)) {
|
||||
if (adopt_line[0] == '#')
|
||||
continue;
|
||||
else if (!strncmp(adopt_line, "lvmlockd", 8)) {
|
||||
unsigned int v_major = 0, v_minor = 0;
|
||||
if ((sscanf(adopt_line, "lvmlockd adopt_version %u.%u", &v_major, &v_minor) != 2) ||
|
||||
(v_major != ADOPT_VERSION_MAJOR))
|
||||
goto fail;
|
||||
|
||||
} else if (!strncmp(adopt_line, "VG:", 3)) {
|
||||
if (!(ls = alloc_lockspace()))
|
||||
goto fail;
|
||||
|
||||
memset(vg_uuid, 0, sizeof(vg_uuid));
|
||||
memset(lm_type_str, 0, sizeof(lm_type_str));
|
||||
|
||||
if (sscanf(adopt_line, "VG: %63s %64s %15s %64s",
|
||||
vg_uuid, ls->vg_name, lm_type_str, ls->vg_args) != 4) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
memcpy(ls->vg_uuid, vg_uuid, 64);
|
||||
|
||||
if ((ls->lm_type = str_to_lm(lm_type_str)) < 0)
|
||||
goto fail;
|
||||
|
||||
list_add(&ls->list, vg_lockd);
|
||||
|
||||
} else if (!strncmp(adopt_line, "LV:", 3)) {
|
||||
if (!(r = alloc_resource()))
|
||||
goto fail;
|
||||
|
||||
r->type = LD_RT_LV;
|
||||
|
||||
memset(vg_uuid, 0, sizeof(vg_uuid));
|
||||
memset(mode, 0, sizeof(mode));
|
||||
|
||||
if (sscanf(adopt_line, "LV: %64s %64s %s %7s %u",
|
||||
vg_uuid, r->name, r->lv_args, mode, &r->version) != 5) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((r->adopt_mode = str_to_mode(mode)) == LD_LK_IV)
|
||||
goto fail;
|
||||
|
||||
if (ls && !memcmp(ls->vg_uuid, vg_uuid, 64)) {
|
||||
list_add(&r->list, &ls->resources);
|
||||
r = NULL;
|
||||
} else {
|
||||
list_for_each_entry(ls2, vg_lockd, list) {
|
||||
if (memcmp(ls2->vg_uuid, vg_uuid, 64))
|
||||
continue;
|
||||
list_add(&r->list, &ls2->resources);
|
||||
r = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (r) {
|
||||
log_error("No lockspace found for resource %s vg_uuid %s", r->name, vg_uuid);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* These are few enough that arrays of function pointers can
|
||||
* be avoided.
|
||||
@@ -2682,7 +2538,7 @@ out_rem:
|
||||
|
||||
log_debug("S %s clearing locks", ls->name);
|
||||
|
||||
(void) clear_locks(ls, free_vg, drop_vg);
|
||||
rv = clear_locks(ls, free_vg, drop_vg);
|
||||
|
||||
/*
|
||||
* Tell any other hosts in the lockspace to leave it
|
||||
@@ -4833,7 +4689,6 @@ static void *client_thread_main(void *arg_in)
|
||||
struct client *cl;
|
||||
struct action *act;
|
||||
struct action *act_un;
|
||||
uint32_t lock_acquire_count = 0, lock_acquire_written = 0;
|
||||
int rv;
|
||||
|
||||
while (1) {
|
||||
@@ -4865,9 +4720,6 @@ static void *client_thread_main(void *arg_in)
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
if (act->flags & LD_AF_LV_LOCK)
|
||||
lock_acquire_count++;
|
||||
|
||||
/*
|
||||
* The client failed after we acquired an LV lock for
|
||||
* it, but before getting this reply saying it's done.
|
||||
@@ -4889,11 +4741,6 @@ static void *client_thread_main(void *arg_in)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (adopt_opt && (lock_acquire_count > lock_acquire_written)) {
|
||||
lock_acquire_written = lock_acquire_count;
|
||||
write_adopt_file();
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue incoming actions for lockspace threads
|
||||
*/
|
||||
@@ -4967,8 +4814,6 @@ static void *client_thread_main(void *arg_in)
|
||||
pthread_mutex_unlock(&client_mutex);
|
||||
}
|
||||
out:
|
||||
if (adopt_opt && lock_acquire_written)
|
||||
unlink(adopt_file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -5001,6 +4846,180 @@ static void close_client_thread(void)
|
||||
log_error("pthread_join client_thread error %d", perrno);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a list of all VGs with a lockd type (sanlock|dlm).
|
||||
* We'll match this list against a list of existing lockspaces that are
|
||||
* found in the lock manager.
|
||||
*
|
||||
* For each of these VGs, also create a struct resource on ls->resources to
|
||||
* represent each LV in the VG that uses a lock. For each of these LVs
|
||||
* that are active, we'll attempt to adopt a lock.
|
||||
*/
|
||||
|
||||
static int get_lockd_vgs(struct list_head *vg_lockd)
|
||||
{
|
||||
/* FIXME: get VGs some other way */
|
||||
return -1;
|
||||
#if 0
|
||||
struct list_head update_vgs;
|
||||
daemon_reply reply;
|
||||
struct dm_config_node *cn;
|
||||
struct dm_config_node *metadata;
|
||||
struct dm_config_node *md_cn;
|
||||
struct dm_config_node *lv_cn;
|
||||
struct lockspace *ls, *safe;
|
||||
struct resource *r;
|
||||
const char *vg_name;
|
||||
const char *vg_uuid;
|
||||
const char *lv_uuid;
|
||||
const char *lock_type;
|
||||
const char *lock_args;
|
||||
char find_str_path[PATH_MAX];
|
||||
int rv = 0;
|
||||
|
||||
INIT_LIST_HEAD(&update_vgs);
|
||||
|
||||
reply = send_lvmetad("vg_list", "token = %s", "skip", NULL);
|
||||
|
||||
if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
|
||||
log_error("vg_list from lvmetad failed %d", reply.error);
|
||||
rv = -EINVAL;
|
||||
goto destroy;
|
||||
}
|
||||
|
||||
if (!(cn = dm_config_find_node(reply.cft->root, "volume_groups"))) {
|
||||
log_error("get_lockd_vgs no vgs");
|
||||
rv = -EINVAL;
|
||||
goto destroy;
|
||||
}
|
||||
|
||||
/* create an update_vgs list of all vg uuids */
|
||||
|
||||
for (cn = cn->child; cn; cn = cn->sib) {
|
||||
vg_uuid = cn->key;
|
||||
|
||||
if (!(ls = alloc_lockspace())) {
|
||||
rv = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
strncpy(ls->vg_uuid, vg_uuid, 64);
|
||||
list_add_tail(&ls->list, &update_vgs);
|
||||
log_debug("get_lockd_vgs %s", vg_uuid);
|
||||
}
|
||||
destroy:
|
||||
daemon_reply_destroy(reply);
|
||||
|
||||
if (rv < 0)
|
||||
goto out;
|
||||
|
||||
/* get vg_name and lock_type for each vg uuid entry in update_vgs */
|
||||
|
||||
list_for_each_entry(ls, &update_vgs, list) {
|
||||
reply = send_lvmetad("vg_lookup",
|
||||
"token = %s", "skip",
|
||||
"uuid = %s", ls->vg_uuid,
|
||||
NULL);
|
||||
|
||||
if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
|
||||
log_error("vg_lookup from lvmetad failed %d", reply.error);
|
||||
rv = -EINVAL;
|
||||
goto next;
|
||||
}
|
||||
|
||||
vg_name = daemon_reply_str(reply, "name", NULL);
|
||||
if (!vg_name) {
|
||||
log_error("get_lockd_vgs %s no name", ls->vg_uuid);
|
||||
rv = -EINVAL;
|
||||
goto next;
|
||||
}
|
||||
|
||||
strncpy(ls->vg_name, vg_name, MAX_NAME);
|
||||
|
||||
metadata = dm_config_find_node(reply.cft->root, "metadata");
|
||||
if (!metadata) {
|
||||
log_error("get_lockd_vgs %s name %s no metadata",
|
||||
ls->vg_uuid, ls->vg_name);
|
||||
rv = -EINVAL;
|
||||
goto next;
|
||||
}
|
||||
|
||||
lock_type = dm_config_find_str(metadata, "metadata/lock_type", NULL);
|
||||
ls->lm_type = str_to_lm(lock_type);
|
||||
|
||||
if ((ls->lm_type != LD_LM_SANLOCK) && (ls->lm_type != LD_LM_DLM)) {
|
||||
log_debug("get_lockd_vgs %s not lockd type", ls->vg_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
lock_args = dm_config_find_str(metadata, "metadata/lock_args", NULL);
|
||||
if (lock_args)
|
||||
strncpy(ls->vg_args, lock_args, MAX_ARGS);
|
||||
|
||||
log_debug("get_lockd_vgs %s lock_type %s lock_args %s",
|
||||
ls->vg_name, lock_type, lock_args ?: "none");
|
||||
|
||||
/*
|
||||
* Make a record (struct resource) of each lv that uses a lock.
|
||||
* For any lv that uses a lock, we'll check if the lv is active
|
||||
* and if so try to adopt a lock for it.
|
||||
*/
|
||||
|
||||
for (md_cn = metadata->child; md_cn; md_cn = md_cn->sib) {
|
||||
if (strcmp(md_cn->key, "logical_volumes"))
|
||||
continue;
|
||||
|
||||
for (lv_cn = md_cn->child; lv_cn; lv_cn = lv_cn->sib) {
|
||||
snprintf(find_str_path, PATH_MAX, "%s/lock_args", lv_cn->key);
|
||||
lock_args = dm_config_find_str(lv_cn, find_str_path, NULL);
|
||||
if (!lock_args)
|
||||
continue;
|
||||
|
||||
snprintf(find_str_path, PATH_MAX, "%s/id", lv_cn->key);
|
||||
lv_uuid = dm_config_find_str(lv_cn, find_str_path, NULL);
|
||||
|
||||
if (!lv_uuid) {
|
||||
log_error("get_lock_vgs no lv id for name %s", lv_cn->key);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(r = alloc_resource())) {
|
||||
rv = -ENOMEM;
|
||||
goto next;
|
||||
}
|
||||
|
||||
r->use_vb = 0;
|
||||
r->type = LD_RT_LV;
|
||||
strncpy(r->name, lv_uuid, MAX_NAME);
|
||||
if (lock_args)
|
||||
strncpy(r->lv_args, lock_args, MAX_ARGS);
|
||||
list_add_tail(&r->list, &ls->resources);
|
||||
log_debug("get_lockd_vgs %s lv %s %s (name %s)",
|
||||
ls->vg_name, r->name, lock_args ? lock_args : "", lv_cn->key);
|
||||
}
|
||||
}
|
||||
next:
|
||||
daemon_reply_destroy(reply);
|
||||
|
||||
if (rv < 0)
|
||||
break;
|
||||
}
|
||||
out:
|
||||
/* Return lockd VG's on the vg_lockd list. */
|
||||
|
||||
list_for_each_entry_safe(ls, safe, &update_vgs, list) {
|
||||
list_del(&ls->list);
|
||||
|
||||
if ((ls->lm_type == LD_LM_SANLOCK) || (ls->lm_type == LD_LM_DLM))
|
||||
list_add_tail(&ls->list, vg_lockd);
|
||||
else
|
||||
free(ls);
|
||||
}
|
||||
|
||||
return rv;
|
||||
#endif
|
||||
}
|
||||
|
||||
static char _dm_uuid[DM_UUID_LEN];
|
||||
|
||||
static char *get_dm_uuid(char *dm_name)
|
||||
@@ -5217,9 +5236,9 @@ static void adopt_locks(void)
|
||||
INIT_LIST_HEAD(&to_unlock);
|
||||
|
||||
/*
|
||||
* Get list of lockspaces from currently running lock managers.
|
||||
* Get list of shared VGs from file written by prior lvmlockd.
|
||||
* Get list of active LVs (in the shared VGs) from the file.
|
||||
* Get list of lockspaces from lock managers.
|
||||
* Get list of VGs from lvmetad with a lockd type.
|
||||
* Get list of active lockd type LVs from /dev.
|
||||
*/
|
||||
|
||||
if (lm_support_dlm() && lm_is_running_dlm()) {
|
||||
@@ -5243,17 +5262,12 @@ static void adopt_locks(void)
|
||||
* Adds a struct lockspace to vg_lockd for each lockd VG.
|
||||
* Adds a struct resource to ls->resources for each LV.
|
||||
*/
|
||||
rv = read_adopt_file(&vg_lockd);
|
||||
rv = get_lockd_vgs(&vg_lockd);
|
||||
if (rv < 0) {
|
||||
log_error("adopt_locks read_adopt_file failed");
|
||||
log_error("adopt_locks get_lockd_vgs failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (list_empty(&vg_lockd)) {
|
||||
log_debug("No lockspaces in adopt file");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* For each resource on each lockspace, check if the
|
||||
* corresponding LV is active. If so, leave the
|
||||
@@ -5492,7 +5506,7 @@ static void adopt_locks(void)
|
||||
goto fail;
|
||||
act->op = LD_OP_LOCK;
|
||||
act->rt = LD_RT_LV;
|
||||
act->mode = r->adopt_mode;
|
||||
act->mode = LD_LK_EX;
|
||||
act->flags = (LD_AF_ADOPT | LD_AF_PERSISTENT);
|
||||
act->client_id = INTERNAL_CLIENT_ID;
|
||||
act->lm_type = ls->lm_type;
|
||||
@@ -5590,9 +5604,8 @@ static void adopt_locks(void)
|
||||
* Adopt failed because the orphan has a different mode
|
||||
* than initially requested. Repeat the lock-adopt operation
|
||||
* with the other mode. N.B. this logic depends on first
|
||||
* trying sh then ex for GL/VG locks; for LV locks the mode
|
||||
* from the adopt file is tried first, the alternate
|
||||
* (if the mode in adopt file was wrong somehow.)
|
||||
* trying sh then ex for GL/VG locks, and ex then sh for
|
||||
* LV locks.
|
||||
*/
|
||||
|
||||
if ((act->rt != LD_RT_LV) && (act->mode == LD_LK_SH)) {
|
||||
@@ -5600,12 +5613,9 @@ static void adopt_locks(void)
|
||||
act->mode = LD_LK_EX;
|
||||
rv = add_lock_action(act);
|
||||
|
||||
} else if (act->rt == LD_RT_LV) {
|
||||
/* LV locks: attempt to adopt the other mode. */
|
||||
if (act->mode == LD_LK_EX)
|
||||
act->mode = LD_LK_SH;
|
||||
else if (act->mode == LD_LK_SH)
|
||||
act->mode = LD_LK_EX;
|
||||
} else if ((act->rt == LD_RT_LV) && (act->mode == LD_LK_EX)) {
|
||||
/* LV locks: attempt to adopt sh after ex failed. */
|
||||
act->mode = LD_LK_SH;
|
||||
rv = add_lock_action(act);
|
||||
|
||||
} else {
|
||||
@@ -5740,13 +5750,10 @@ static void adopt_locks(void)
|
||||
if (count_start_fail || count_adopt_fail)
|
||||
goto fail;
|
||||
|
||||
unlink(adopt_file);
|
||||
write_adopt_file();
|
||||
log_debug("adopt_locks done");
|
||||
return;
|
||||
|
||||
fail:
|
||||
unlink(adopt_file);
|
||||
log_error("adopt_locks failed, reset host");
|
||||
}
|
||||
|
||||
@@ -6021,8 +6028,6 @@ static void usage(char *prog, FILE *file)
|
||||
fprintf(file, " Set path to the pid file. [%s]\n", LVMLOCKD_PIDFILE);
|
||||
fprintf(file, " --socket-path | -s <path>\n");
|
||||
fprintf(file, " Set path to the socket to listen on. [%s]\n", LVMLOCKD_SOCKET);
|
||||
fprintf(file, " --adopt-file <path>\n");
|
||||
fprintf(file, " Set path to the adopt file. [%s]\n", LVMLOCKD_ADOPT_FILE);
|
||||
fprintf(file, " --syslog-priority | -S err|warning|debug\n");
|
||||
fprintf(file, " Write log messages from this level up to syslog. [%s]\n", _syslog_num_to_name(LOG_SYSLOG_PRIO));
|
||||
fprintf(file, " --gl-type | -g <str>\n");
|
||||
@@ -6040,14 +6045,14 @@ static void usage(char *prog, FILE *file)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
daemon_state ds = {
|
||||
.name = "lvmlockd",
|
||||
.daemon_main = main_loop,
|
||||
.daemon_init = NULL,
|
||||
.daemon_fini = NULL,
|
||||
.pidfile = getenv("LVM_LVMLOCKD_PIDFILE"),
|
||||
.socket_path = getenv("LVM_LVMLOCKD_SOCKET"),
|
||||
.protocol = lvmlockd_protocol,
|
||||
.protocol_version = lvmlockd_protocol_version,
|
||||
.daemon_init = NULL,
|
||||
.daemon_fini = NULL,
|
||||
.daemon_main = main_loop,
|
||||
.name = "lvmlockd",
|
||||
};
|
||||
|
||||
static struct option long_options[] = {
|
||||
@@ -6058,7 +6063,6 @@ int main(int argc, char *argv[])
|
||||
{"daemon-debug", no_argument, 0, 'D' },
|
||||
{"pid-file", required_argument, 0, 'p' },
|
||||
{"socket-path", required_argument, 0, 's' },
|
||||
{"adopt-file", required_argument, 0, 128 },
|
||||
{"gl-type", required_argument, 0, 'g' },
|
||||
{"host-id", required_argument, 0, 'i' },
|
||||
{"host-id-file", required_argument, 0, 'F' },
|
||||
@@ -6081,9 +6085,6 @@ int main(int argc, char *argv[])
|
||||
switch (c) {
|
||||
case '0':
|
||||
break;
|
||||
case 128:
|
||||
adopt_file = strdup(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0], stdout);
|
||||
exit(EXIT_SUCCESS);
|
||||
@@ -6145,9 +6146,6 @@ int main(int argc, char *argv[])
|
||||
if (!ds.socket_path)
|
||||
ds.socket_path = LVMLOCKD_SOCKET;
|
||||
|
||||
if (!adopt_file)
|
||||
adopt_file = LVMLOCKD_ADOPT_FILE;
|
||||
|
||||
/* runs daemon_main/main_loop */
|
||||
daemon_start(ds);
|
||||
|
||||
|
@@ -327,7 +327,8 @@ int lm_rem_resource_dlm(struct lockspace *ls, struct resource *r)
|
||||
log_error("S %s R %s rem_resource_dlm unlock error %d", ls->name, r->name, rv);
|
||||
}
|
||||
out:
|
||||
free(rdd->vb);
|
||||
if (rdd->vb)
|
||||
free(rdd->vb);
|
||||
|
||||
memset(rdd, 0, sizeof(struct rd_dlm));
|
||||
r->lm_init = 0;
|
||||
@@ -397,18 +398,12 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
(void *)1, (void *)1, (void *)1,
|
||||
NULL, NULL);
|
||||
|
||||
if (rv == -1 && (errno == EAGAIN)) {
|
||||
if (rv == -1 && errno == -EAGAIN) {
|
||||
log_debug("S %s R %s adopt_dlm adopt mode %d try other mode",
|
||||
ls->name, r->name, ld_mode);
|
||||
rv = -EUCLEAN;
|
||||
goto fail;
|
||||
}
|
||||
if (rv == -1 && (errno == ENOENT)) {
|
||||
log_debug("S %s R %s adopt_dlm adopt mode %d no lock",
|
||||
ls->name, r->name, ld_mode);
|
||||
rv = -ENOENT;
|
||||
goto fail;
|
||||
}
|
||||
if (rv < 0) {
|
||||
log_debug("S %s R %s adopt_dlm mode %d flags %x error %d errno %d",
|
||||
ls->name, r->name, mode, flags, rv, errno);
|
||||
|
@@ -11,8 +11,6 @@
|
||||
#ifndef _LVM_LVMLOCKD_INTERNAL_H
|
||||
#define _LVM_LVMLOCKD_INTERNAL_H
|
||||
|
||||
#include "base/memory/container_of.h"
|
||||
|
||||
#define MAX_NAME 64
|
||||
#define MAX_ARGS 64
|
||||
|
||||
@@ -147,7 +145,6 @@ struct resource {
|
||||
char name[MAX_NAME+1]; /* vg name or lv name */
|
||||
int8_t type; /* resource type LD_RT_ */
|
||||
int8_t mode;
|
||||
int8_t adopt_mode;
|
||||
unsigned int sh_count; /* number of sh locks on locks list */
|
||||
uint32_t version;
|
||||
uint32_t last_client_id; /* last client_id to lock or unlock resource */
|
||||
@@ -158,7 +155,7 @@ struct resource {
|
||||
struct list_head locks;
|
||||
struct list_head actions;
|
||||
char lv_args[MAX_ARGS+1];
|
||||
char lm_data[]; /* lock manager specific data */
|
||||
char lm_data[0]; /* lock manager specific data */
|
||||
};
|
||||
|
||||
#define LD_LF_PERSISTENT 0x00000001
|
||||
@@ -219,6 +216,10 @@ struct val_blk {
|
||||
/* lm_unlock flags */
|
||||
#define LMUF_FREE_VG 0x00000001
|
||||
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||
|
||||
static inline void INIT_LIST_HEAD(struct list_head *list)
|
||||
{
|
||||
list->next = list;
|
||||
|
@@ -1503,7 +1503,8 @@ out:
|
||||
fail:
|
||||
if (lms && lms->sock)
|
||||
close(lms->sock);
|
||||
free(lms);
|
||||
if (lms)
|
||||
free(lms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1633,7 +1634,8 @@ int lm_rem_resource_sanlock(struct lockspace *ls, struct resource *r)
|
||||
|
||||
/* FIXME: assert r->mode == UN or unlock if it's not? */
|
||||
|
||||
free(rds->vb);
|
||||
if (rds->vb)
|
||||
free(rds->vb);
|
||||
|
||||
memset(rds, 0, sizeof(struct rd_sanlock));
|
||||
r->lm_init = 0;
|
||||
|
@@ -19,11 +19,12 @@ SOURCES = lvmpolld-core.c lvmpolld-data-utils.c lvmpolld-cmd-utils.c
|
||||
|
||||
TARGETS = lvmpolld
|
||||
|
||||
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
|
||||
CFLOW_TARGET := $(TARGETS)
|
||||
|
||||
.PHONY: install_lvmpolld
|
||||
|
||||
CFLOW_LIST = $(SOURCES)
|
||||
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
|
||||
CFLOW_TARGET = lvmpolld
|
||||
|
||||
include $(top_builddir)/make.tmpl
|
||||
|
||||
CFLAGS += $(EXTRA_EXEC_CFLAGS)
|
||||
|
@@ -92,12 +92,6 @@ const char **cmdargv_ctr(const struct lvmpolld_lv *pdlv, const char *lvm_binary,
|
||||
if (!add_to_cmd_arr(&cmd_argv, "-An", &i))
|
||||
goto err;
|
||||
|
||||
if (pdlv->devicesfile) {
|
||||
if (!add_to_cmd_arr(&cmd_argv, "--devicesfile", &i) ||
|
||||
!add_to_cmd_arr(&cmd_argv, pdlv->devicesfile, &i))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* terminating NULL */
|
||||
if (!add_to_cmd_arr(&cmd_argv, NULL, &i))
|
||||
goto err;
|
||||
|
@@ -149,7 +149,7 @@ static void _lvmpolld_global_unlock(struct lvmpolld_state *ls)
|
||||
static int _fini(struct daemon_state *s)
|
||||
{
|
||||
int done;
|
||||
const struct timespec t = { .tv_nsec = 10000000 }; /* .01 sec */
|
||||
const struct timespec t = { .tv_nsec = 250000000 }; /* .25 sec */
|
||||
struct lvmpolld_state *ls = s->private;
|
||||
|
||||
DEBUGLOG(s, "fini");
|
||||
@@ -236,7 +236,9 @@ static int poll_for_output(struct lvmpolld_lv *pdlv, struct lvmpolld_thread_data
|
||||
}
|
||||
|
||||
while (1) {
|
||||
r = poll(fds, 2, pdlv_get_timeout(pdlv) * 1000);
|
||||
do {
|
||||
r = poll(fds, 2, pdlv_get_timeout(pdlv) * 1000);
|
||||
} while (r < 0 && errno == EINTR);
|
||||
|
||||
DEBUGLOG(pdlv->ls, "%s: %s %d", PD_LOG_PREFIX, "poll() returned", r);
|
||||
if (r < 0) {
|
||||
@@ -553,15 +555,14 @@ static struct lvmpolld_lv *construct_pdlv(request req, struct lvmpolld_state *ls
|
||||
const char *interval, const char *id,
|
||||
const char *vgname, const char *lvname,
|
||||
const char *sysdir, enum poll_type type,
|
||||
unsigned abort_polling, unsigned uinterval,
|
||||
const char *devicesfile)
|
||||
unsigned abort_polling, unsigned uinterval)
|
||||
{
|
||||
const char **cmdargv, **cmdenvp;
|
||||
struct lvmpolld_lv *pdlv;
|
||||
unsigned handle_missing_pvs = daemon_request_int(req, LVMPD_PARM_HANDLE_MISSING_PVS, 0);
|
||||
|
||||
pdlv = pdlv_create(ls, id, vgname, lvname, sysdir, type,
|
||||
interval, uinterval, pdst, devicesfile);
|
||||
interval, uinterval, pdst);
|
||||
|
||||
if (!pdlv) {
|
||||
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to create internal LV data structure.");
|
||||
@@ -620,7 +621,6 @@ static response poll_init(client_handle h, struct lvmpolld_state *ls, request re
|
||||
const char *lvname = daemon_request_str(req, LVMPD_PARM_LVNAME, NULL);
|
||||
const char *vgname = daemon_request_str(req, LVMPD_PARM_VGNAME, NULL);
|
||||
const char *sysdir = daemon_request_str(req, LVMPD_PARM_SYSDIR, NULL);
|
||||
const char *devicesfile = daemon_request_str(req, LVMPD_PARM_DEVICESFILE, NULL);
|
||||
unsigned abort_polling = daemon_request_int(req, LVMPD_PARM_ABORT, 0);
|
||||
|
||||
assert(type < POLL_TYPE_MAX);
|
||||
@@ -680,7 +680,7 @@ static response poll_init(client_handle h, struct lvmpolld_state *ls, request re
|
||||
pdlv->init_rq_count++; /* safe. protected by store lock */
|
||||
} else {
|
||||
pdlv = construct_pdlv(req, ls, pdst, interval, id, vgname,
|
||||
lvname, sysdir, type, abort_polling, 2 * uinterval, devicesfile);
|
||||
lvname, sysdir, type, abort_polling, 2 * uinterval);
|
||||
if (!pdlv) {
|
||||
pdst_unlock(pdst);
|
||||
free(id);
|
||||
|
@@ -93,13 +93,11 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
|
||||
const char *vgname, const char *lvname,
|
||||
const char *sysdir, enum poll_type type,
|
||||
const char *sinterval, unsigned pdtimeout,
|
||||
struct lvmpolld_store *pdst,
|
||||
const char *devicesfile)
|
||||
struct lvmpolld_store *pdst)
|
||||
{
|
||||
char *lvmpolld_id = strdup(id), /* copy */
|
||||
*full_lvname = _construct_full_lvname(vgname, lvname), /* copy */
|
||||
*lvm_system_dir_env = _construct_lvm_system_dir_env(sysdir); /* copy */
|
||||
char *devicesfile_dup = devicesfile ? strdup(devicesfile) : NULL;
|
||||
|
||||
struct lvmpolld_lv tmp = {
|
||||
.ls = ls,
|
||||
@@ -107,7 +105,6 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
|
||||
.lvmpolld_id = lvmpolld_id,
|
||||
.lvid = _get_lvid(lvmpolld_id, sysdir),
|
||||
.lvname = full_lvname,
|
||||
.devicesfile = devicesfile_dup,
|
||||
.lvm_system_dir_env = lvm_system_dir_env,
|
||||
.sinterval = strdup(sinterval), /* copy */
|
||||
.pdtimeout = pdtimeout < MIN_POLLING_TIMEOUT ? MIN_POLLING_TIMEOUT : pdtimeout,
|
||||
@@ -127,7 +124,6 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
|
||||
return pdlv;
|
||||
|
||||
err:
|
||||
free((void *)devicesfile_dup);
|
||||
free((void *)full_lvname);
|
||||
free((void *)lvmpolld_id);
|
||||
free((void *)lvm_system_dir_env);
|
||||
@@ -140,7 +136,6 @@ err:
|
||||
void pdlv_destroy(struct lvmpolld_lv *pdlv)
|
||||
{
|
||||
free((void *)pdlv->lvmpolld_id);
|
||||
free((void *)pdlv->devicesfile);
|
||||
free((void *)pdlv->lvname);
|
||||
free((void *)pdlv->sinterval);
|
||||
free((void *)pdlv->lvm_system_dir_env);
|
||||
|
@@ -49,7 +49,6 @@ struct lvmpolld_lv {
|
||||
const enum poll_type type;
|
||||
const char *const lvid;
|
||||
const char *const lvmpolld_id;
|
||||
const char *const devicesfile;
|
||||
const char *const lvname; /* full vg/lv name */
|
||||
const unsigned pdtimeout; /* in seconds */
|
||||
const char *const sinterval;
|
||||
@@ -102,8 +101,7 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
|
||||
const char *vgname, const char *lvname,
|
||||
const char *sysdir, enum poll_type type,
|
||||
const char *sinterval, unsigned pdtimeout,
|
||||
struct lvmpolld_store *pdst,
|
||||
const char *devicesfile);
|
||||
struct lvmpolld_store *pdst);
|
||||
|
||||
/* only call with appropriate struct lvmpolld_store lock held */
|
||||
void pdlv_destroy(struct lvmpolld_lv *pdlv);
|
||||
|
@@ -35,7 +35,6 @@
|
||||
#define LVMPD_PARM_SYSDIR "sysdir"
|
||||
#define LVMPD_PARM_VALUE "value" /* either retcode or signal value */
|
||||
#define LVMPD_PARM_VGNAME "vgname"
|
||||
#define LVMPD_PARM_DEVICESFILE "devicesfile"
|
||||
|
||||
#define LVMPD_RESP_FAILED "failed"
|
||||
#define LVMPD_RESP_FINISHED "finished"
|
||||
|
@@ -164,20 +164,20 @@ struct dm_info {
|
||||
struct dm_deps {
|
||||
uint32_t count;
|
||||
uint32_t filler;
|
||||
uint64_t device[];
|
||||
uint64_t device[0];
|
||||
};
|
||||
|
||||
struct dm_names {
|
||||
uint64_t dev;
|
||||
uint32_t next; /* Offset to next struct from start of this struct */
|
||||
char name[];
|
||||
char name[0];
|
||||
};
|
||||
|
||||
struct dm_versions {
|
||||
uint32_t next; /* Offset to next struct from start of this struct */
|
||||
uint32_t version[3];
|
||||
|
||||
char name[];
|
||||
char name[0];
|
||||
};
|
||||
|
||||
int dm_get_library_version(char *version, size_t size);
|
||||
@@ -234,7 +234,6 @@ int dm_task_suppress_identical_reload(struct dm_task *dmt);
|
||||
int dm_task_secure_data(struct dm_task *dmt);
|
||||
int dm_task_retry_remove(struct dm_task *dmt);
|
||||
int dm_task_deferred_remove(struct dm_task *dmt);
|
||||
void dm_task_skip_reload_params_compare(struct dm_task *dmt);
|
||||
|
||||
/*
|
||||
* Record timestamp immediately after the ioctl returns.
|
||||
@@ -384,7 +383,7 @@ int dm_get_status_cache(struct dm_pool *mem, const char *params,
|
||||
struct dm_status_cache **status);
|
||||
|
||||
struct dm_status_writecache {
|
||||
uint64_t error;
|
||||
uint32_t error;
|
||||
uint64_t total_blocks;
|
||||
uint64_t free_blocks;
|
||||
uint64_t writeback_blocks;
|
||||
@@ -393,15 +392,6 @@ struct dm_status_writecache {
|
||||
int dm_get_status_writecache(struct dm_pool *mem, const char *params,
|
||||
struct dm_status_writecache **status);
|
||||
|
||||
struct dm_status_integrity {
|
||||
uint64_t number_of_mismatches;
|
||||
uint64_t provided_data_sectors;
|
||||
uint64_t recalc_sector;
|
||||
};
|
||||
|
||||
int dm_get_status_integrity(struct dm_pool *mem, const char *params,
|
||||
struct dm_status_integrity **status);
|
||||
|
||||
/*
|
||||
* Parse params from STATUS call for snapshot target
|
||||
*
|
||||
@@ -951,8 +941,6 @@ struct writecache_settings {
|
||||
uint64_t autocommit_time; /* in milliseconds */
|
||||
uint32_t fua;
|
||||
uint32_t nofua;
|
||||
uint32_t cleaner;
|
||||
uint32_t max_age;
|
||||
|
||||
/*
|
||||
* Allow an unrecognized key and its val to be passed to the kernel for
|
||||
@@ -972,8 +960,6 @@ struct writecache_settings {
|
||||
unsigned autocommit_time_set:1;
|
||||
unsigned fua_set:1;
|
||||
unsigned nofua_set:1;
|
||||
unsigned cleaner_set:1;
|
||||
unsigned max_age_set:1;
|
||||
};
|
||||
|
||||
int dm_tree_node_add_writecache_target(struct dm_tree_node *node,
|
||||
@@ -984,42 +970,12 @@ int dm_tree_node_add_writecache_target(struct dm_tree_node *node,
|
||||
uint32_t writecache_block_size,
|
||||
struct writecache_settings *settings);
|
||||
|
||||
struct integrity_settings {
|
||||
char mode[8];
|
||||
uint32_t tag_size;
|
||||
uint32_t block_size; /* optional table param always set by lvm */
|
||||
const char *internal_hash; /* optional table param always set by lvm */
|
||||
|
||||
uint32_t journal_sectors;
|
||||
uint32_t interleave_sectors;
|
||||
uint32_t buffer_sectors;
|
||||
uint32_t journal_watermark;
|
||||
uint32_t commit_time;
|
||||
uint32_t bitmap_flush_interval;
|
||||
uint64_t sectors_per_bit;
|
||||
|
||||
unsigned journal_sectors_set:1;
|
||||
unsigned interleave_sectors_set:1;
|
||||
unsigned buffer_sectors_set:1;
|
||||
unsigned journal_watermark_set:1;
|
||||
unsigned commit_time_set:1;
|
||||
unsigned bitmap_flush_interval_set:1;
|
||||
unsigned sectors_per_bit_set:1;
|
||||
};
|
||||
|
||||
int dm_tree_node_add_integrity_target(struct dm_tree_node *node,
|
||||
uint64_t size,
|
||||
const char *origin_uuid,
|
||||
const char *meta_uuid,
|
||||
struct integrity_settings *settings,
|
||||
int recalculate);
|
||||
|
||||
/*
|
||||
* VDO target
|
||||
*/
|
||||
int dm_tree_node_add_vdo_target(struct dm_tree_node *node,
|
||||
uint64_t size,
|
||||
const char *vdo_pool_name,
|
||||
const char *data_uuid,
|
||||
uint64_t data_size,
|
||||
const struct dm_vdo_target_params *param);
|
||||
@@ -1072,10 +1028,10 @@ int dm_tree_node_add_replicator_dev_target(struct dm_tree_node *node,
|
||||
#define DM_THIN_MIN_DATA_BLOCK_SIZE (UINT32_C(128))
|
||||
#define DM_THIN_MAX_DATA_BLOCK_SIZE (UINT32_C(2097152))
|
||||
/*
|
||||
* Max supported size for thin pool metadata device (17045913600 bytes)
|
||||
* Max supported size for thin pool metadata device (17112760320 bytes)
|
||||
* Limitation is hardcoded into the kernel and bigger device size
|
||||
* is not accepted.
|
||||
* drivers/md/dm-thin-metadata.h THIN_METADATA_MAX_SECTORS
|
||||
* But here DM_THIN_MAX_METADATA_SIZE got defined incorrectly
|
||||
* Correct size is (UINT64_C(255) * ((1 << 14) - 64) * (4096 / (1 << 9)))
|
||||
*/
|
||||
#define DM_THIN_MAX_METADATA_SIZE (UINT64_C(255) * (1 << 14) * (4096 / (1 << 9)) - 256 * 1024)
|
||||
|
||||
@@ -1088,16 +1044,6 @@ int dm_tree_node_add_thin_pool_target(struct dm_tree_node *node,
|
||||
uint64_t low_water_mark,
|
||||
unsigned skip_block_zeroing);
|
||||
|
||||
int dm_tree_node_add_thin_pool_target_v1(struct dm_tree_node *node,
|
||||
uint64_t size,
|
||||
uint64_t transaction_id,
|
||||
const char *metadata_uuid,
|
||||
const char *pool_uuid,
|
||||
uint32_t data_block_size,
|
||||
uint64_t low_water_mark,
|
||||
unsigned skip_block_zeroing,
|
||||
unsigned crop_metadata);
|
||||
|
||||
/* Supported messages for thin provision target */
|
||||
typedef enum {
|
||||
DM_THIN_MESSAGE_CREATE_SNAP, /* device_id, origin_id */
|
||||
@@ -1328,7 +1274,7 @@ int dm_bit_get_next(dm_bitset_t bs, int last_bit);
|
||||
int dm_bit_get_last(dm_bitset_t bs);
|
||||
int dm_bit_get_prev(dm_bitset_t bs, int last_bit);
|
||||
|
||||
#define DM_BITS_PER_INT ((unsigned)sizeof(int) * CHAR_BIT)
|
||||
#define DM_BITS_PER_INT (sizeof(int) * CHAR_BIT)
|
||||
|
||||
#define dm_bit(bs, i) \
|
||||
((bs)[((i) / DM_BITS_PER_INT) + 1] & (0x1 << ((i) & (DM_BITS_PER_INT - 1))))
|
||||
|
@@ -242,3 +242,18 @@ bad:
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
/*
|
||||
* Maintain backward compatibility with older versions that did not
|
||||
* accept a 'min_num_bits' argument to dm_bitset_parse_list().
|
||||
*/
|
||||
dm_bitset_t dm_bitset_parse_list_v1_02_129(const char *str, struct dm_pool *mem);
|
||||
dm_bitset_t dm_bitset_parse_list_v1_02_129(const char *str, struct dm_pool *mem)
|
||||
{
|
||||
return dm_bitset_parse_list(str, mem, 0);
|
||||
}
|
||||
|
||||
#else /* if defined(__GNUC__) */
|
||||
|
||||
#endif
|
||||
|
@@ -205,7 +205,7 @@ static int _get_proc_number(const char *file, const char *name,
|
||||
}
|
||||
|
||||
while (getline(&line, &len, fl) != -1) {
|
||||
if (sscanf(line, "%u %255s\n", &num, &nm[0]) == 2) {
|
||||
if (sscanf(line, "%d %255s\n", &num, &nm[0]) == 2) {
|
||||
if (!strcmp(name, nm)) {
|
||||
if (number) {
|
||||
*number = num;
|
||||
@@ -493,10 +493,7 @@ static void _dm_task_free_targets(struct dm_task *dmt)
|
||||
|
||||
for (t = dmt->head; t; t = n) {
|
||||
n = t->next;
|
||||
if (dmt->secure_data)
|
||||
_dm_zfree_string(t->params);
|
||||
else
|
||||
free(t->params);
|
||||
_dm_zfree_string(t->params);
|
||||
free(t->type);
|
||||
free(t);
|
||||
}
|
||||
@@ -507,10 +504,7 @@ static void _dm_task_free_targets(struct dm_task *dmt)
|
||||
void dm_task_destroy(struct dm_task *dmt)
|
||||
{
|
||||
_dm_task_free_targets(dmt);
|
||||
if (dmt->secure_data)
|
||||
_dm_zfree_dmi(dmt->dmi.v4);
|
||||
else
|
||||
free(dmt->dmi.v4);
|
||||
_dm_zfree_dmi(dmt->dmi.v4);
|
||||
free(dmt->dev_name);
|
||||
free(dmt->mangled_dev_name);
|
||||
free(dmt->newname);
|
||||
@@ -811,11 +805,6 @@ int dm_task_suppress_identical_reload(struct dm_task *dmt)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void dm_task_skip_reload_params_compare(struct dm_task *dmt)
|
||||
{
|
||||
dmt->skip_reload_params_compare = 1;
|
||||
}
|
||||
|
||||
int dm_task_set_add_node(struct dm_task *dmt, dm_add_node_t add_node)
|
||||
{
|
||||
switch (add_node) {
|
||||
@@ -1118,7 +1107,7 @@ static int _add_params(int type)
|
||||
|
||||
static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
|
||||
{
|
||||
size_t min_size;
|
||||
const size_t min_size = 16 * 1024;
|
||||
const int (*version)[3];
|
||||
|
||||
struct dm_ioctl *dmi;
|
||||
@@ -1137,18 +1126,6 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
|
||||
else if (dmt->head)
|
||||
log_debug_activation(INTERNAL_ERROR "dm '%s' ioctl should not define parameters.",
|
||||
_cmd_data_v4[dmt->type].name);
|
||||
switch (dmt->type) {
|
||||
case DM_DEVICE_CREATE:
|
||||
case DM_DEVICE_DEPS:
|
||||
case DM_DEVICE_LIST:
|
||||
case DM_DEVICE_STATUS:
|
||||
case DM_DEVICE_TABLE:
|
||||
case DM_DEVICE_TARGET_MSG:
|
||||
min_size = 16 * 1024;
|
||||
break;
|
||||
default:
|
||||
min_size = 2 * 1024;
|
||||
}
|
||||
|
||||
if (count && (dmt->sector || dmt->message)) {
|
||||
log_error("targets and message are incompatible");
|
||||
@@ -1352,7 +1329,7 @@ static int _process_mapper_dir(struct dm_task *dmt)
|
||||
}
|
||||
|
||||
if (closedir(d))
|
||||
log_sys_debug("closedir", dir);
|
||||
log_sys_error("closedir", dir);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -1598,36 +1575,11 @@ static int _reload_with_suppression_v4(struct dm_task *dmt)
|
||||
len = strlen(t2->params);
|
||||
while (len-- > 0 && t2->params[len] == ' ')
|
||||
t2->params[len] = '\0';
|
||||
|
||||
if (t1->start != t2->start) {
|
||||
log_debug("reload %u:%u diff start %llu %llu type %s %s", task->major, task->minor,
|
||||
(unsigned long long)t1->start, (unsigned long long)t2->start, t1->type, t2->type);
|
||||
if ((t1->start != t2->start) ||
|
||||
(t1->length != t2->length) ||
|
||||
(strcmp(t1->type, t2->type)) ||
|
||||
(strcmp(t1->params, t2->params)))
|
||||
goto no_match;
|
||||
}
|
||||
if (t1->length != t2->length) {
|
||||
log_debug("reload %u:%u diff length %llu %llu type %s %s", task->major, task->minor,
|
||||
(unsigned long long)t1->length, (unsigned long long)t2->length, t1->type, t2->type);
|
||||
goto no_match;
|
||||
}
|
||||
if (strcmp(t1->type, t2->type)) {
|
||||
log_debug("reload %u:%u diff type %s %s", task->major, task->minor, t1->type, t2->type);
|
||||
goto no_match;
|
||||
}
|
||||
if (strcmp(t1->params, t2->params)) {
|
||||
if (dmt->skip_reload_params_compare) {
|
||||
log_debug("reload %u:%u diff params ignore for type %s",
|
||||
task->major, task->minor, t1->type);
|
||||
log_debug("reload params1 %s", t1->params);
|
||||
log_debug("reload params2 %s", t2->params);
|
||||
} else {
|
||||
log_debug("reload %u:%u diff params for type %s",
|
||||
task->major, task->minor, t1->type);
|
||||
log_debug("reload params1 %s", t1->params);
|
||||
log_debug("reload params2 %s", t2->params);
|
||||
goto no_match;
|
||||
}
|
||||
}
|
||||
|
||||
t1 = t1->next;
|
||||
t2 = t2->next;
|
||||
}
|
||||
@@ -2209,3 +2161,52 @@ void dm_lib_exit(void)
|
||||
_version_ok = 1;
|
||||
_version_checked = 0;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
/*
|
||||
* Maintain binary backward compatibility.
|
||||
* Version script mechanism works with 'gcc' compatible compilers only.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This following code is here to retain ABI compatibility after adding
|
||||
* the field deferred_remove to struct dm_info in version 1.02.89.
|
||||
*
|
||||
* Binaries linked against version 1.02.88 of libdevmapper or earlier
|
||||
* will use this function that returns dm_info without the
|
||||
* deferred_remove field.
|
||||
*
|
||||
* Binaries compiled against version 1.02.89 onwards will use
|
||||
* the new function dm_task_get_info_with_deferred_remove due to the
|
||||
* #define.
|
||||
*
|
||||
* N.B. Keep this function at the end of the file to make sure that
|
||||
* no code in this file accidentally calls it.
|
||||
*/
|
||||
|
||||
int dm_task_get_info_base(struct dm_task *dmt, struct dm_info *info);
|
||||
int dm_task_get_info_base(struct dm_task *dmt, struct dm_info *info)
|
||||
{
|
||||
struct dm_info new_info;
|
||||
|
||||
if (!dm_task_get_info(dmt, &new_info))
|
||||
return 0;
|
||||
|
||||
memcpy(info, &new_info, offsetof(struct dm_info, deferred_remove));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dm_task_get_info_with_deferred_remove(struct dm_task *dmt, struct dm_info *info);
|
||||
int dm_task_get_info_with_deferred_remove(struct dm_task *dmt, struct dm_info *info)
|
||||
{
|
||||
struct dm_info new_info;
|
||||
|
||||
if (!dm_task_get_info(dmt, &new_info))
|
||||
return 0;
|
||||
|
||||
memcpy(info, &new_info, offsetof(struct dm_info, internal_suspend));
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
@@ -59,7 +59,6 @@ struct dm_task {
|
||||
int skip_lockfs;
|
||||
int query_inactive_table;
|
||||
int suppress_identical_reload;
|
||||
int skip_reload_params_compare;
|
||||
dm_add_node_t add_node;
|
||||
uint64_t existing_table_size;
|
||||
int cookie_set;
|
||||
|
@@ -382,7 +382,7 @@ static int _find_dm_name_of_device(dev_t st_rdev, char *buf, size_t buf_len)
|
||||
}
|
||||
|
||||
if (closedir(d))
|
||||
log_sys_debug("closedir", _dm_dir);
|
||||
log_sys_error("closedir", _dm_dir);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -512,7 +512,7 @@ int unmangle_string(const char *str, const char *str_name, size_t len,
|
||||
int strict = mode != DM_STRING_MANGLING_NONE;
|
||||
char str_rest[DM_NAME_LEN];
|
||||
size_t i, j;
|
||||
unsigned int code;
|
||||
int code;
|
||||
int r = 0;
|
||||
|
||||
if (!str || !buf)
|
||||
@@ -931,7 +931,7 @@ int dm_task_add_target(struct dm_task *dmt, uint64_t start, uint64_t size,
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
static int _selabel_lookup(const char *path, mode_t mode,
|
||||
char **scontext)
|
||||
security_context_t *scontext)
|
||||
{
|
||||
#ifdef HAVE_SELINUX_LABEL_H
|
||||
if (!_selabel_handle &&
|
||||
@@ -974,7 +974,7 @@ static int _is_selinux_enabled(void)
|
||||
int dm_prepare_selinux_context(const char *path, mode_t mode)
|
||||
{
|
||||
#ifdef HAVE_SELINUX
|
||||
char *scontext = NULL;
|
||||
security_context_t scontext = NULL;
|
||||
|
||||
if (_is_selinux_enabled() <= 0)
|
||||
return 1;
|
||||
@@ -1002,7 +1002,7 @@ int dm_prepare_selinux_context(const char *path, mode_t mode)
|
||||
int dm_set_selinux_context(const char *path, mode_t mode)
|
||||
{
|
||||
#ifdef HAVE_SELINUX
|
||||
char *scontext = NULL;
|
||||
security_context_t scontext = NULL;
|
||||
|
||||
if (_is_selinux_enabled() <= 0)
|
||||
return 1;
|
||||
@@ -1224,7 +1224,7 @@ int get_dev_node_read_ahead(const char *dev_name, uint32_t major, uint32_t minor
|
||||
int len;
|
||||
int r = 1;
|
||||
int fd;
|
||||
long read_ahead_long = 0;
|
||||
long read_ahead_long;
|
||||
|
||||
/*
|
||||
* If we know the device number, use sysfs if we can.
|
||||
@@ -1445,7 +1445,7 @@ struct node_op_parms {
|
||||
char *old_name;
|
||||
int warn_if_udev_failed;
|
||||
unsigned rely_on_udev;
|
||||
char names[];
|
||||
char names[0];
|
||||
};
|
||||
|
||||
static void _store_str(char **pos, char **ptr, const char *str)
|
||||
@@ -2012,8 +2012,7 @@ static int _sysfs_get_kernel_name(uint32_t major, uint32_t minor, char *buf, siz
|
||||
log_sys_error("readlink", sysfs_path);
|
||||
else {
|
||||
log_sys_debug("readlink", sysfs_path);
|
||||
r = _sysfs_find_kernel_name(major, minor, buf, buf_size);
|
||||
goto out;
|
||||
return _sysfs_find_kernel_name(major, minor, buf, buf_size);
|
||||
}
|
||||
goto bad;
|
||||
}
|
||||
@@ -2034,7 +2033,6 @@ static int _sysfs_get_kernel_name(uint32_t major, uint32_t minor, char *buf, siz
|
||||
strcpy(buf, name);
|
||||
r = 1;
|
||||
bad:
|
||||
out:
|
||||
free(temp_buf);
|
||||
free(sysfs_path);
|
||||
|
||||
|
@@ -599,7 +599,7 @@ static struct dm_config_node *_section(struct parser *p, struct dm_config_node *
|
||||
match(TOK_IDENTIFIER);
|
||||
}
|
||||
|
||||
if (!*str) {
|
||||
if (!strlen(str)) {
|
||||
log_error("Parse error at byte %" PRIptrdiff_t " (line %d): empty section identifier",
|
||||
p->tb - p->fb + 1, p->line);
|
||||
return NULL;
|
||||
@@ -983,7 +983,7 @@ static const char *_find_config_str(const void *start, node_lookup_fn find_fn,
|
||||
}
|
||||
|
||||
if (fail)
|
||||
log_very_verbose("%s not found in config: defaulting to \"%s\"",
|
||||
log_very_verbose("%s not found in config: defaulting to %s",
|
||||
path, fail);
|
||||
return fail;
|
||||
}
|
||||
|
@@ -38,7 +38,6 @@ enum {
|
||||
SEG_STRIPED,
|
||||
SEG_ZERO,
|
||||
SEG_WRITECACHE,
|
||||
SEG_INTEGRITY,
|
||||
SEG_THIN_POOL,
|
||||
SEG_THIN,
|
||||
SEG_VDO,
|
||||
@@ -79,7 +78,6 @@ static const struct {
|
||||
{ SEG_STRIPED, "striped" },
|
||||
{ SEG_ZERO, "zero"},
|
||||
{ SEG_WRITECACHE, "writecache"},
|
||||
{ SEG_INTEGRITY, "integrity"},
|
||||
{ SEG_THIN_POOL, "thin-pool"},
|
||||
{ SEG_THIN, "thin"},
|
||||
{ SEG_VDO, "vdo" },
|
||||
@@ -223,11 +221,6 @@ struct load_segment {
|
||||
int writecache_pmem; /* writecache, 1 if pmem, 0 if ssd */
|
||||
uint32_t writecache_block_size; /* writecache, in bytes */
|
||||
struct writecache_settings writecache_settings; /* writecache */
|
||||
|
||||
uint64_t integrity_data_sectors; /* integrity (provided_data_sectors) */
|
||||
struct dm_tree_node *integrity_meta_node; /* integrity */
|
||||
struct integrity_settings integrity_settings; /* integrity */
|
||||
int integrity_recalculate; /* integrity */
|
||||
};
|
||||
|
||||
/* Per-device properties */
|
||||
@@ -274,16 +267,6 @@ struct load_properties {
|
||||
*/
|
||||
unsigned delay_resume_if_extended;
|
||||
|
||||
/*
|
||||
* When comparing table lines to decide if a reload is
|
||||
* needed, ignore any differences betwen the lvm device
|
||||
* params and the kernel-reported device params.
|
||||
* dm-integrity reports many internal parameters on the
|
||||
* table line when lvm does not explicitly set them,
|
||||
* causing lvm and the kernel to have differing params.
|
||||
*/
|
||||
unsigned skip_reload_params_compare;
|
||||
|
||||
/*
|
||||
* Call node_send_messages(), set to 2 if there are messages
|
||||
* When != 0, it validates matching transaction id, thus thin-pools
|
||||
@@ -380,13 +363,13 @@ struct dm_tree *dm_tree_create(void)
|
||||
dtree->mem = dmem;
|
||||
dtree->optional_uuid_suffixes = NULL;
|
||||
|
||||
if (!(dtree->devs = dm_hash_create(61))) {
|
||||
if (!(dtree->devs = dm_hash_create(8))) {
|
||||
log_error("dtree hash creation failed");
|
||||
dm_pool_destroy(dtree->mem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(dtree->uuids = dm_hash_create(31))) {
|
||||
if (!(dtree->uuids = dm_hash_create(32))) {
|
||||
log_error("dtree uuid hash creation failed");
|
||||
dm_hash_destroy(dtree->devs);
|
||||
dm_pool_destroy(dtree->mem);
|
||||
@@ -1589,37 +1572,8 @@ static int _thin_pool_node_message(struct dm_tree_node *dnode, struct thin_messa
|
||||
}
|
||||
|
||||
if (!_node_message(dnode->info.major, dnode->info.minor,
|
||||
tm->expected_errno, buf)) {
|
||||
switch (m->type) {
|
||||
case DM_THIN_MESSAGE_CREATE_SNAP:
|
||||
case DM_THIN_MESSAGE_CREATE_THIN:
|
||||
if (errno == EEXIST) {
|
||||
/*
|
||||
* ATM errno from ioctl() is preserved through code error path chain
|
||||
* If this would ever change, another way need to be used to
|
||||
* obtain result from failed DM message
|
||||
*/
|
||||
log_error("Thin pool %s already contain thin device with device_id %u.",
|
||||
_node_name(dnode), m->u.m_create_snap.device_id);
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* Give some useful advice how to solve this problem,
|
||||
* until lvconvert --repair can handle this automatically
|
||||
*/
|
||||
log_error("Manual intervention may be required to remove device dev_id=%u in thin pool metadata.",
|
||||
m->u.m_create_snap.device_id);
|
||||
log_error("Optionally new thin volume with device_id=%u can be manually added into a volume group.",
|
||||
m->u.m_create_snap.device_id);
|
||||
log_warn("WARNING: When uncertain how to do this, contact support!");
|
||||
return 0;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
return_0;
|
||||
}
|
||||
|
||||
}
|
||||
tm->expected_errno, buf))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1666,15 +1620,6 @@ static int _thin_pool_node_send_messages(struct dm_tree_node *dnode,
|
||||
if (!have_messages || !send)
|
||||
return 1; /* transaction_id is matching */
|
||||
|
||||
if (stp.fail || stp.read_only || stp.needs_check) {
|
||||
log_error("Cannot send messages to thin pool %s%s%s%s.",
|
||||
_node_name(dnode),
|
||||
stp.fail ? " in failed state" : "",
|
||||
stp.read_only ? " with read only metadata" : "",
|
||||
stp.needs_check ? " which needs check first" : "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
dm_list_iterate_items(tmsg, &seg->thin_messages) {
|
||||
if (!(_thin_pool_node_message(dnode, tmsg)))
|
||||
return_0;
|
||||
@@ -2136,7 +2081,7 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _create_node(struct dm_tree_node *dnode, struct dm_tree_node *parent)
|
||||
static int _create_node(struct dm_tree_node *dnode)
|
||||
{
|
||||
int r = 0;
|
||||
struct dm_task *dmt;
|
||||
@@ -2185,15 +2130,38 @@ static int _create_node(struct dm_tree_node *dnode, struct dm_tree_node *parent)
|
||||
"Unable to get DM task info for %s.",
|
||||
dnode->name);
|
||||
}
|
||||
|
||||
if (r)
|
||||
dm_list_add_h(&parent->activated, &dnode->activated_list);
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* _remove_node
|
||||
*
|
||||
* This function is only used to remove a DM device that has failed
|
||||
* to load any table.
|
||||
*/
|
||||
static int _remove_node(struct dm_tree_node *dnode)
|
||||
{
|
||||
if (!dnode->info.exists)
|
||||
return 1;
|
||||
|
||||
if (dnode->info.live_table || dnode->info.inactive_table) {
|
||||
log_error(INTERNAL_ERROR
|
||||
"_remove_node called on device with loaded table(s).");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_deactivate_node(dnode->name, dnode->info.major, dnode->info.minor,
|
||||
&dnode->dtree->cookie, dnode->udev_flags, 0)) {
|
||||
log_error("Failed to clean-up device with no table: %s.",
|
||||
_node_name(dnode));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _build_dev_string(char *devbuf, size_t bufsize, struct dm_tree_node *node)
|
||||
{
|
||||
if (!dm_format_dev(devbuf, bufsize, node->info.major, node->info.minor)) {
|
||||
@@ -2382,7 +2350,7 @@ static int _mirror_emit_segment_line(struct dm_task *dmt, struct load_segment *s
|
||||
|
||||
EMIT_PARAMS(pos, " %u ", seg->mirror_area_count);
|
||||
|
||||
if (!_emit_areas_line(dmt, seg, params, paramsize, &pos))
|
||||
if (_emit_areas_line(dmt, seg, params, paramsize, &pos) <= 0)
|
||||
return_0;
|
||||
|
||||
if (handle_errors)
|
||||
@@ -2584,7 +2552,7 @@ static int _raid_emit_segment_line(struct dm_task *dmt, uint32_t major,
|
||||
/* Print number of metadata/data device pairs */
|
||||
EMIT_PARAMS(pos, " %u", area_count);
|
||||
|
||||
if (!_emit_areas_line(dmt, seg, params, paramsize, &pos))
|
||||
if (_emit_areas_line(dmt, seg, params, paramsize, &pos) <= 0)
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
@@ -2685,10 +2653,6 @@ static int _writecache_emit_segment_line(struct dm_task *dmt,
|
||||
count += 1;
|
||||
if (seg->writecache_settings.nofua_set)
|
||||
count += 1;
|
||||
if (seg->writecache_settings.cleaner_set && seg->writecache_settings.cleaner)
|
||||
count += 1;
|
||||
if (seg->writecache_settings.max_age_set)
|
||||
count += 2;
|
||||
if (seg->writecache_settings.new_key)
|
||||
count += 2;
|
||||
|
||||
@@ -2732,14 +2696,6 @@ static int _writecache_emit_segment_line(struct dm_task *dmt,
|
||||
EMIT_PARAMS(pos, " nofua");
|
||||
}
|
||||
|
||||
if (seg->writecache_settings.cleaner_set && seg->writecache_settings.cleaner) {
|
||||
EMIT_PARAMS(pos, " cleaner");
|
||||
}
|
||||
|
||||
if (seg->writecache_settings.max_age_set) {
|
||||
EMIT_PARAMS(pos, " max_age %u", seg->writecache_settings.max_age);
|
||||
}
|
||||
|
||||
if (seg->writecache_settings.new_key) {
|
||||
EMIT_PARAMS(pos, " %s %s",
|
||||
seg->writecache_settings.new_key,
|
||||
@@ -2749,87 +2705,6 @@ static int _writecache_emit_segment_line(struct dm_task *dmt,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _integrity_emit_segment_line(struct dm_task *dmt,
|
||||
struct load_segment *seg,
|
||||
char *params, size_t paramsize)
|
||||
{
|
||||
struct integrity_settings *set = &seg->integrity_settings;
|
||||
int pos = 0;
|
||||
int count;
|
||||
char origin_dev[DM_FORMAT_DEV_BUFSIZE];
|
||||
char meta_dev[DM_FORMAT_DEV_BUFSIZE];
|
||||
|
||||
if (!_build_dev_string(origin_dev, sizeof(origin_dev), seg->origin))
|
||||
return_0;
|
||||
|
||||
if (seg->integrity_meta_node &&
|
||||
!_build_dev_string(meta_dev, sizeof(meta_dev), seg->integrity_meta_node))
|
||||
return_0;
|
||||
|
||||
count = 3; /* block_size, internal_hash, fix_padding options are always passed */
|
||||
|
||||
if (seg->integrity_meta_node)
|
||||
count++;
|
||||
|
||||
if (seg->integrity_recalculate)
|
||||
count++;
|
||||
|
||||
if (set->journal_sectors_set)
|
||||
count++;
|
||||
if (set->interleave_sectors_set)
|
||||
count++;
|
||||
if (set->buffer_sectors_set)
|
||||
count++;
|
||||
if (set->journal_watermark_set)
|
||||
count++;
|
||||
if (set->commit_time_set)
|
||||
count++;
|
||||
if (set->bitmap_flush_interval_set)
|
||||
count++;
|
||||
if (set->sectors_per_bit_set)
|
||||
count++;
|
||||
|
||||
EMIT_PARAMS(pos, "%s 0 %u %s %d fix_padding block_size:%u internal_hash:%s",
|
||||
origin_dev,
|
||||
set->tag_size,
|
||||
set->mode,
|
||||
count,
|
||||
set->block_size,
|
||||
set->internal_hash);
|
||||
|
||||
if (seg->integrity_meta_node)
|
||||
EMIT_PARAMS(pos, " meta_device:%s", meta_dev);
|
||||
|
||||
if (seg->integrity_recalculate)
|
||||
EMIT_PARAMS(pos, " recalculate");
|
||||
|
||||
if (set->journal_sectors_set)
|
||||
EMIT_PARAMS(pos, " journal_sectors:%u", set->journal_sectors);
|
||||
|
||||
if (set->interleave_sectors_set)
|
||||
EMIT_PARAMS(pos, " ineterleave_sectors:%u", set->interleave_sectors);
|
||||
|
||||
if (set->buffer_sectors_set)
|
||||
EMIT_PARAMS(pos, " buffer_sectors:%u", set->buffer_sectors);
|
||||
|
||||
if (set->journal_watermark_set)
|
||||
EMIT_PARAMS(pos, " journal_watermark:%u", set->journal_watermark);
|
||||
|
||||
if (set->commit_time_set)
|
||||
EMIT_PARAMS(pos, " commit_time:%u", set->commit_time);
|
||||
|
||||
if (set->bitmap_flush_interval_set)
|
||||
EMIT_PARAMS(pos, " bitmap_flush_interval:%u", set->bitmap_flush_interval);
|
||||
|
||||
if (set->sectors_per_bit_set)
|
||||
EMIT_PARAMS(pos, " sectors_per_bit:%llu", (unsigned long long)set->sectors_per_bit);
|
||||
|
||||
if (!dm_task_secure_data(dmt))
|
||||
stack;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _thin_pool_emit_segment_line(struct dm_task *dmt,
|
||||
struct load_segment *seg,
|
||||
char *params, size_t paramsize)
|
||||
@@ -2930,6 +2805,7 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
|
||||
size_t paramsize)
|
||||
{
|
||||
int pos = 0;
|
||||
int r;
|
||||
int target_type_is_raid = 0;
|
||||
char originbuf[DM_FORMAT_DEV_BUFSIZE], cowbuf[DM_FORMAT_DEV_BUFSIZE];
|
||||
|
||||
@@ -2940,7 +2816,8 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
|
||||
break;
|
||||
case SEG_MIRRORED:
|
||||
/* Mirrors are pretty complicated - now in separate function */
|
||||
if (!_mirror_emit_segment_line(dmt, seg, params, paramsize))
|
||||
r = _mirror_emit_segment_line(dmt, seg, params, paramsize);
|
||||
if (!r)
|
||||
return_0;
|
||||
break;
|
||||
case SEG_SNAPSHOT:
|
||||
@@ -2961,7 +2838,7 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
|
||||
EMIT_PARAMS(pos, "%u %u ", seg->area_count, seg->stripe_size);
|
||||
break;
|
||||
case SEG_VDO:
|
||||
if (!_vdo_emit_segment_line(dmt, seg, params, paramsize))
|
||||
if (!(r = _vdo_emit_segment_line(dmt, seg, params, paramsize)))
|
||||
return_0;
|
||||
break;
|
||||
case SEG_CRYPT:
|
||||
@@ -2990,8 +2867,9 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
|
||||
case SEG_RAID6_LA_6:
|
||||
case SEG_RAID6_RA_6:
|
||||
target_type_is_raid = 1;
|
||||
if (!_raid_emit_segment_line(dmt, major, minor, seg, seg_start,
|
||||
params, paramsize))
|
||||
r = _raid_emit_segment_line(dmt, major, minor, seg, seg_start,
|
||||
params, paramsize);
|
||||
if (!r)
|
||||
return_0;
|
||||
|
||||
break;
|
||||
@@ -3011,10 +2889,6 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
|
||||
if (!_writecache_emit_segment_line(dmt, seg, params, paramsize))
|
||||
return_0;
|
||||
break;
|
||||
case SEG_INTEGRITY:
|
||||
if (!_integrity_emit_segment_line(dmt, seg, params, paramsize))
|
||||
return_0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(seg->type) {
|
||||
@@ -3027,14 +2901,14 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
|
||||
case SEG_THIN:
|
||||
case SEG_CACHE:
|
||||
case SEG_WRITECACHE:
|
||||
case SEG_INTEGRITY:
|
||||
break;
|
||||
case SEG_CRYPT:
|
||||
case SEG_LINEAR:
|
||||
case SEG_STRIPED:
|
||||
if (!_emit_areas_line(dmt, seg, params, paramsize, &pos))
|
||||
return_0;
|
||||
|
||||
if ((r = _emit_areas_line(dmt, seg, params, paramsize, &pos)) <= 0) {
|
||||
stack;
|
||||
return r;
|
||||
}
|
||||
if (!params[0]) {
|
||||
log_error("No parameters supplied for %s target "
|
||||
"%u:%u.", _dm_segtypes[seg->type].target,
|
||||
@@ -3131,9 +3005,6 @@ static int _load_node(struct dm_tree_node *dnode)
|
||||
if (!dm_task_suppress_identical_reload(dmt))
|
||||
log_warn("WARNING: Failed to suppress reload of identical tables.");
|
||||
|
||||
if (dnode->props.skip_reload_params_compare)
|
||||
dm_task_skip_reload_params_compare(dmt);
|
||||
|
||||
if ((r = dm_task_run(dmt))) {
|
||||
r = dm_task_get_info(dmt, &dnode->info);
|
||||
if (r && !dnode->info.inactive_table)
|
||||
@@ -3152,8 +3023,8 @@ static int _load_node(struct dm_tree_node *dnode)
|
||||
if (!existing_table_size && dnode->props.delay_resume_if_new)
|
||||
dnode->props.size_changed = 0;
|
||||
|
||||
log_debug_activation("Table size changed from %" PRIu64 " to %" PRIu64 " for %s.%s",
|
||||
existing_table_size,
|
||||
log_debug_activation("Table size changed from %" PRIu64 " to %"
|
||||
PRIu64 " for %s.%s", existing_table_size,
|
||||
seg_start, _node_name(dnode),
|
||||
dnode->props.size_changed ? "" : " (Ignoring.)");
|
||||
|
||||
@@ -3205,16 +3076,6 @@ static int _dm_tree_revert_activated(struct dm_tree_node *parent)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _dm_tree_wait_and_revert_activated(struct dm_tree_node *dnode)
|
||||
{
|
||||
if (!dm_udev_wait(dm_tree_get_cookie(dnode)))
|
||||
stack;
|
||||
|
||||
dm_tree_set_cookie(dnode, 0);
|
||||
|
||||
return _dm_tree_revert_activated(dnode);
|
||||
}
|
||||
|
||||
int dm_tree_preload_children(struct dm_tree_node *dnode,
|
||||
const char *uuid_prefix,
|
||||
size_t uuid_prefix_len)
|
||||
@@ -3244,7 +3105,7 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
|
||||
return_0;
|
||||
|
||||
/* FIXME Cope if name exists with no uuid? */
|
||||
if (!child->info.exists && !(node_created = _create_node(child, dnode)))
|
||||
if (!child->info.exists && !(node_created = _create_node(child)))
|
||||
return_0;
|
||||
|
||||
/* Propagate delayed resume from exteded child node */
|
||||
@@ -3254,22 +3115,28 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
|
||||
if (!child->info.inactive_table &&
|
||||
child->props.segment_count &&
|
||||
!_load_node(child)) {
|
||||
stack;
|
||||
/*
|
||||
* If the table load fails, try to device in the kernel
|
||||
* together with other created and preloaded devices.
|
||||
* If the table load does not succeed, we remove the
|
||||
* device in the kernel that would otherwise have an
|
||||
* empty table. This makes the create + load of the
|
||||
* device atomic. However, if other dependencies have
|
||||
* already been created and loaded; this code is
|
||||
* insufficient to remove those - only the node
|
||||
* encountering the table load failure is removed.
|
||||
*/
|
||||
if (!_dm_tree_wait_and_revert_activated(dnode))
|
||||
stack;
|
||||
r = 0;
|
||||
continue;
|
||||
if (node_created) {
|
||||
if (!_remove_node(child))
|
||||
return_0;
|
||||
if (!dm_udev_wait(dm_tree_get_cookie(dnode)))
|
||||
stack;
|
||||
dm_tree_set_cookie(dnode, 0);
|
||||
(void) _dm_tree_revert_activated(child);
|
||||
}
|
||||
return_0;
|
||||
}
|
||||
|
||||
/* No resume for a device without parents or with unchanged or smaller size */
|
||||
if (!dm_tree_node_num_children(child, 1))
|
||||
continue;
|
||||
|
||||
if (child->props.size_changed <= 0)
|
||||
if (!dm_tree_node_num_children(child, 1) || (child->props.size_changed <= 0))
|
||||
continue;
|
||||
|
||||
if (!child->info.inactive_table && !child->info.suspended)
|
||||
@@ -3280,19 +3147,28 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
|
||||
&child->info, &child->dtree->cookie, child->udev_flags,
|
||||
child->info.suspended)) {
|
||||
log_error("Unable to resume %s.", _node_name(child));
|
||||
if (!_dm_tree_wait_and_revert_activated(dnode))
|
||||
stack;
|
||||
/* If the device was not previously active, we might as well remove this node. */
|
||||
if (!child->info.live_table &&
|
||||
!_deactivate_node(child->name, child->info.major, child->info.minor,
|
||||
&child->dtree->cookie, child->udev_flags, 0))
|
||||
log_error("Unable to deactivate %s.", _node_name(child));
|
||||
r = 0;
|
||||
/* Each child is handled independently */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (node_created) {
|
||||
/* Collect newly introduced devices for revert */
|
||||
dm_list_add_h(&dnode->activated, &child->activated_list);
|
||||
|
||||
/* When creating new node also check transaction_id. */
|
||||
if (child->props.send_messages &&
|
||||
!_node_send_messages(child, uuid_prefix, uuid_prefix_len, 0)) {
|
||||
stack;
|
||||
if (!_dm_tree_wait_and_revert_activated(dnode))
|
||||
if (!dm_udev_wait(dm_tree_get_cookie(dnode)))
|
||||
stack;
|
||||
dm_tree_set_cookie(dnode, 0);
|
||||
(void) _dm_tree_revert_activated(dnode);
|
||||
r = 0;
|
||||
continue;
|
||||
}
|
||||
@@ -3862,48 +3738,6 @@ int dm_tree_node_add_writecache_target(struct dm_tree_node *node,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dm_tree_node_add_integrity_target(struct dm_tree_node *node,
|
||||
uint64_t size,
|
||||
const char *origin_uuid,
|
||||
const char *meta_uuid,
|
||||
struct integrity_settings *settings,
|
||||
int recalculate)
|
||||
{
|
||||
struct load_segment *seg;
|
||||
|
||||
if (!(seg = _add_segment(node, SEG_INTEGRITY, size)))
|
||||
return_0;
|
||||
|
||||
if (!meta_uuid) {
|
||||
log_error("No integrity meta uuid.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(seg->integrity_meta_node = dm_tree_find_node_by_uuid(node->dtree, meta_uuid))) {
|
||||
log_error("Missing integrity's meta uuid %s.", meta_uuid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_link_tree_nodes(node, seg->integrity_meta_node))
|
||||
return_0;
|
||||
|
||||
if (!(seg->origin = dm_tree_find_node_by_uuid(node->dtree, origin_uuid))) {
|
||||
log_error("Missing integrity's origin uuid %s.", origin_uuid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_link_tree_nodes(node, seg->origin))
|
||||
return_0;
|
||||
|
||||
memcpy(&seg->integrity_settings, settings, sizeof(struct integrity_settings));
|
||||
|
||||
seg->integrity_recalculate = recalculate;
|
||||
|
||||
node->props.skip_reload_params_compare = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dm_tree_node_add_replicator_target(struct dm_tree_node *node,
|
||||
uint64_t size,
|
||||
const char *rlog_uuid,
|
||||
@@ -3977,24 +3811,6 @@ int dm_tree_node_add_thin_pool_target(struct dm_tree_node *node,
|
||||
uint32_t data_block_size,
|
||||
uint64_t low_water_mark,
|
||||
unsigned skip_block_zeroing)
|
||||
{
|
||||
return dm_tree_node_add_thin_pool_target_v1(node, size, transaction_id,
|
||||
metadata_uuid, pool_uuid,
|
||||
data_block_size,
|
||||
low_water_mark,
|
||||
skip_block_zeroing,
|
||||
1);
|
||||
}
|
||||
|
||||
int dm_tree_node_add_thin_pool_target_v1(struct dm_tree_node *node,
|
||||
uint64_t size,
|
||||
uint64_t transaction_id,
|
||||
const char *metadata_uuid,
|
||||
const char *pool_uuid,
|
||||
uint32_t data_block_size,
|
||||
uint64_t low_water_mark,
|
||||
unsigned skip_block_zeroing,
|
||||
unsigned crop_metadata)
|
||||
{
|
||||
struct load_segment *seg, *mseg;
|
||||
uint64_t devsize = 0;
|
||||
@@ -4022,18 +3838,17 @@ int dm_tree_node_add_thin_pool_target_v1(struct dm_tree_node *node,
|
||||
if (!_link_tree_nodes(node, seg->metadata))
|
||||
return_0;
|
||||
|
||||
if (crop_metadata)
|
||||
/* FIXME: more complex target may need more tweaks */
|
||||
dm_list_iterate_items(mseg, &seg->metadata->props.segs) {
|
||||
devsize += mseg->size;
|
||||
if (devsize > DM_THIN_MAX_METADATA_SIZE) {
|
||||
log_debug_activation("Ignoring %" PRIu64 " of device.",
|
||||
devsize - DM_THIN_MAX_METADATA_SIZE);
|
||||
mseg->size -= (devsize - DM_THIN_MAX_METADATA_SIZE);
|
||||
devsize = DM_THIN_MAX_METADATA_SIZE;
|
||||
/* FIXME: drop remaining segs */
|
||||
}
|
||||
/* FIXME: more complex target may need more tweaks */
|
||||
dm_list_iterate_items(mseg, &seg->metadata->props.segs) {
|
||||
devsize += mseg->size;
|
||||
if (devsize > DM_THIN_MAX_METADATA_SIZE) {
|
||||
log_debug_activation("Ignoring %" PRIu64 " of device.",
|
||||
devsize - DM_THIN_MAX_METADATA_SIZE);
|
||||
mseg->size -= (devsize - DM_THIN_MAX_METADATA_SIZE);
|
||||
devsize = DM_THIN_MAX_METADATA_SIZE;
|
||||
/* FIXME: drop remaining segs */
|
||||
}
|
||||
}
|
||||
|
||||
if (!(seg->pool = dm_tree_find_node_by_uuid(node->dtree, pool_uuid))) {
|
||||
log_error("Missing pool uuid %s.", pool_uuid);
|
||||
@@ -4328,9 +4143,63 @@ void dm_tree_node_set_callback(struct dm_tree_node *dnode,
|
||||
dnode->callback_data = data;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
/*
|
||||
* Backward compatible implementations.
|
||||
*
|
||||
* Keep these at the end of the file to make sure that
|
||||
* no code in this file accidentally calls it.
|
||||
*/
|
||||
|
||||
/* Backward compatible dm_tree_node_size_changed() implementations. */
|
||||
int dm_tree_node_size_changed_base(const struct dm_tree_node *dnode);
|
||||
int dm_tree_node_size_changed_base(const struct dm_tree_node *dnode)
|
||||
{
|
||||
/* Base does not make difference between smaller and bigger */
|
||||
return dm_tree_node_size_changed(dnode) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retain ABI compatibility after adding the DM_CACHE_FEATURE_METADATA2
|
||||
* in version 1.02.138.
|
||||
*
|
||||
* Binaries compiled against version 1.02.138 onwards will use
|
||||
* the new function dm_tree_node_add_cache_target which detects unknown
|
||||
* feature flags and returns error for them.
|
||||
*/
|
||||
int dm_tree_node_add_cache_target_base(struct dm_tree_node *node,
|
||||
uint64_t size,
|
||||
uint64_t feature_flags, /* DM_CACHE_FEATURE_* */
|
||||
const char *metadata_uuid,
|
||||
const char *data_uuid,
|
||||
const char *origin_uuid,
|
||||
const char *policy_name,
|
||||
const struct dm_config_node *policy_settings,
|
||||
uint32_t data_block_size);
|
||||
int dm_tree_node_add_cache_target_base(struct dm_tree_node *node,
|
||||
uint64_t size,
|
||||
uint64_t feature_flags,
|
||||
const char *metadata_uuid,
|
||||
const char *data_uuid,
|
||||
const char *origin_uuid,
|
||||
const char *policy_name,
|
||||
const struct dm_config_node *policy_settings,
|
||||
uint32_t data_block_size)
|
||||
{
|
||||
/* Old version supported only these FEATURE bits, others were ignored so masked them */
|
||||
static const uint64_t _mask =
|
||||
DM_CACHE_FEATURE_WRITEBACK |
|
||||
DM_CACHE_FEATURE_WRITETHROUGH |
|
||||
DM_CACHE_FEATURE_PASSTHROUGH;
|
||||
|
||||
return dm_tree_node_add_cache_target(node, size, feature_flags & _mask,
|
||||
metadata_uuid, data_uuid, origin_uuid,
|
||||
policy_name, policy_settings, 0, 0, 0, 0, data_block_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
int dm_tree_node_add_vdo_target(struct dm_tree_node *node,
|
||||
uint64_t size,
|
||||
const char *vdo_pool_name,
|
||||
const char *data_uuid,
|
||||
uint64_t data_size,
|
||||
const struct dm_vdo_target_params *vtp)
|
||||
@@ -4352,7 +4221,7 @@ int dm_tree_node_add_vdo_target(struct dm_tree_node *node,
|
||||
return_0;
|
||||
|
||||
seg->vdo_params = *vtp;
|
||||
seg->vdo_name = vdo_pool_name;
|
||||
seg->vdo_name = node->name;
|
||||
seg->vdo_data_size = data_size;
|
||||
|
||||
node->props.send_messages = 2;
|
||||
|
@@ -110,7 +110,7 @@ int dm_is_empty_dir(const char *dir)
|
||||
DIR *d;
|
||||
|
||||
if (!(d = opendir(dir))) {
|
||||
log_sys_debug("opendir", dir);
|
||||
log_sys_error("opendir", dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ int dm_is_empty_dir(const char *dir)
|
||||
break;
|
||||
|
||||
if (closedir(d))
|
||||
log_sys_debug("closedir", dir);
|
||||
log_sys_error("closedir", dir);
|
||||
|
||||
return dirent ? 0 : 1;
|
||||
}
|
||||
|
@@ -492,7 +492,7 @@ static int _report_field_string_list(struct dm_report *rh,
|
||||
delimiter = ",";
|
||||
delimiter_len = strlen(delimiter);
|
||||
|
||||
i = pos = 0;
|
||||
i = pos = len = 0;
|
||||
dm_list_iterate_items(sl, data) {
|
||||
arr[i].str = sl->str;
|
||||
if (!sort) {
|
||||
@@ -749,11 +749,10 @@ static void _display_fields_more(struct dm_report *rh,
|
||||
id_len = strlen(type->prefix) + 3;
|
||||
|
||||
for (f = 0; fields[f].report_fn; f++) {
|
||||
if (!(type = _find_type(rh, fields[f].type))) {
|
||||
log_debug(INTERNAL_ERROR "Field type undefined.");
|
||||
continue;
|
||||
}
|
||||
desc = (type->desc) ? : " ";
|
||||
if ((type = _find_type(rh, fields[f].type)) && type->desc)
|
||||
desc = type->desc;
|
||||
else
|
||||
desc = " ";
|
||||
if (desc != last_desc) {
|
||||
if (*last_desc)
|
||||
log_warn(" ");
|
||||
@@ -2474,7 +2473,7 @@ dm_percent_t dm_make_percent(uint64_t numerator, uint64_t denominator)
|
||||
|
||||
int dm_report_value_cache_set(struct dm_report *rh, const char *name, const void *data)
|
||||
{
|
||||
if (!rh->value_cache && (!(rh->value_cache = dm_hash_create(63)))) {
|
||||
if (!rh->value_cache && (!(rh->value_cache = dm_hash_create(64)))) {
|
||||
log_error("Failed to create cache for values used during reporting.");
|
||||
return 0;
|
||||
}
|
||||
|
@@ -366,8 +366,8 @@ int dm_get_status_writecache(struct dm_pool *mem, const char *params,
|
||||
if (!(s = dm_pool_zalloc(mem, sizeof(struct dm_status_writecache))))
|
||||
return_0;
|
||||
|
||||
if (sscanf(params, "%llu %llu %llu %llu",
|
||||
(unsigned long long *)&s->error,
|
||||
if (sscanf(params, "%u %llu %llu %llu",
|
||||
&s->error,
|
||||
(unsigned long long *)&s->total_blocks,
|
||||
(unsigned long long *)&s->free_blocks,
|
||||
(unsigned long long *)&s->writeback_blocks) != 4) {
|
||||
@@ -380,33 +380,6 @@ int dm_get_status_writecache(struct dm_pool *mem, const char *params,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dm_get_status_integrity(struct dm_pool *mem, const char *params,
|
||||
struct dm_status_integrity **status)
|
||||
{
|
||||
struct dm_status_integrity *s;
|
||||
char recalc_str[16] = "\0";
|
||||
|
||||
if (!(s = dm_pool_zalloc(mem, sizeof(*s))))
|
||||
return_0;
|
||||
|
||||
if (sscanf(params, "%llu %llu %s",
|
||||
(unsigned long long *)&s->number_of_mismatches,
|
||||
(unsigned long long *)&s->provided_data_sectors,
|
||||
recalc_str) != 3) {
|
||||
log_error("Failed to parse integrity params: %s.", params);
|
||||
dm_pool_free(mem, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (recalc_str[0] == '-')
|
||||
s->recalc_sector = 0;
|
||||
else
|
||||
s->recalc_sector = strtoull(recalc_str, NULL, 0);
|
||||
|
||||
*status = s;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parse_thin_pool_status(const char *params, struct dm_status_thin_pool *s)
|
||||
{
|
||||
int pos;
|
||||
|
@@ -183,7 +183,7 @@ struct dm_target_spec {
|
||||
struct dm_target_deps {
|
||||
uint32_t count; /* Array size */
|
||||
uint32_t padding; /* unused */
|
||||
uint64_t dev[]; /* out */
|
||||
uint64_t dev[0]; /* out */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -193,7 +193,7 @@ struct dm_name_list {
|
||||
uint64_t dev;
|
||||
uint32_t next; /* offset to the next record from
|
||||
the _start_ of this */
|
||||
char name[];
|
||||
char name[0];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -203,7 +203,7 @@ struct dm_target_versions {
|
||||
uint32_t next;
|
||||
uint32_t version[3];
|
||||
|
||||
char name[];
|
||||
char name[0];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -212,7 +212,7 @@ struct dm_target_versions {
|
||||
struct dm_target_msg {
|
||||
uint64_t sector; /* Device sector */
|
||||
|
||||
char message[];
|
||||
char message[0];
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -98,7 +98,7 @@ void dm_pools_check_leaks(void)
|
||||
p->orig_pool,
|
||||
p->name, p->stats.bytes);
|
||||
#else
|
||||
log_error(" [%p] %s", (void *)p, p->name);
|
||||
log_error(" [%p] %s", p, p->name);
|
||||
#endif
|
||||
}
|
||||
pthread_mutex_unlock(&_dm_pools_mutex);
|
||||
|
@@ -94,7 +94,7 @@ journal_watermark:number
|
||||
|
||||
commit_time:number
|
||||
Commit time in milliseconds. When this time passes, the journal is
|
||||
written. The journal is also written immediately if the FLUSH
|
||||
written. The journal is also written immediatelly if the FLUSH
|
||||
request is received.
|
||||
|
||||
internal_hash:algorithm(:key) (the key is optional)
|
||||
|
2
include/.gitignore
vendored
2
include/.gitignore
vendored
@@ -1,3 +1 @@
|
||||
*.h
|
||||
.symlinks
|
||||
.symlinks_created
|
||||
|
@@ -126,15 +126,9 @@
|
||||
/* Library version */
|
||||
#undef DM_LIB_VERSION
|
||||
|
||||
/* Define to 1 to include the LVM editline shell. */
|
||||
#undef EDITLINE_SUPPORT
|
||||
|
||||
/* Path to fsadm binary. */
|
||||
#undef FSADM_PATH
|
||||
|
||||
/* Define to use GNU versioning in the shared library. */
|
||||
#undef GNU_SYMVER
|
||||
|
||||
/* Define to 1 if you have the `alarm' function. */
|
||||
#undef HAVE_ALARM
|
||||
|
||||
@@ -157,9 +151,6 @@
|
||||
/* Define to 1 if you have the `atexit' function. */
|
||||
#undef HAVE_ATEXIT
|
||||
|
||||
/* Define if ioctl BLKZEROOUT can be used for device zeroing. */
|
||||
#undef HAVE_BLKZEROOUT
|
||||
|
||||
/* Define to 1 if canonicalize_file_name is available. */
|
||||
#undef HAVE_CANONICALIZE_FILE_NAME
|
||||
|
||||
@@ -185,9 +176,6 @@
|
||||
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
|
||||
#undef HAVE_DOPRNT
|
||||
|
||||
/* Define to 1 if you have the <editline/readline.h> header file. */
|
||||
#undef HAVE_EDITLINE_READLINE_H
|
||||
|
||||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#undef HAVE_ERRNO_H
|
||||
|
||||
@@ -543,9 +531,6 @@
|
||||
/* Define to 1 if the system has the `__builtin_clzll' built-in function */
|
||||
#undef HAVE___BUILTIN_CLZLL
|
||||
|
||||
/* Define to 1 to include built-in support for integrity. */
|
||||
#undef INTEGRITY_INTERNAL
|
||||
|
||||
/* Internalization package */
|
||||
#undef INTL_PACKAGE
|
||||
|
||||
|
@@ -15,13 +15,11 @@
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
top_builddir = @top_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
|
||||
SOURCES =\
|
||||
activate/activate.c \
|
||||
cache/lvmcache.c \
|
||||
writecache/writecache.c \
|
||||
integrity/integrity.c \
|
||||
cache_segtype/cache.c \
|
||||
commands/toolcontext.c \
|
||||
config/config.c \
|
||||
@@ -30,7 +28,6 @@ SOURCES =\
|
||||
device/bcache.c \
|
||||
device/bcache-utils.c \
|
||||
device/dev-cache.c \
|
||||
device/device_id.c \
|
||||
device/dev-ext.c \
|
||||
device/dev-io.c \
|
||||
device/dev-md.c \
|
||||
@@ -54,7 +51,6 @@ SOURCES =\
|
||||
filters/filter-usable.c \
|
||||
filters/filter-internal.c \
|
||||
filters/filter-signature.c \
|
||||
filters/filter-deviceid.c \
|
||||
format_text/archive.c \
|
||||
format_text/archiver.c \
|
||||
format_text/export.c \
|
||||
@@ -71,7 +67,6 @@ SOURCES =\
|
||||
log/log.c \
|
||||
metadata/cache_manip.c \
|
||||
metadata/writecache_manip.c \
|
||||
metadata/integrity_manip.c \
|
||||
metadata/lv.c \
|
||||
metadata/lv_manip.c \
|
||||
metadata/merge.c \
|
||||
@@ -79,7 +74,6 @@ SOURCES =\
|
||||
metadata/mirror.c \
|
||||
metadata/pool_manip.c \
|
||||
metadata/pv.c \
|
||||
metadata/pv_list.c \
|
||||
metadata/pv_manip.c \
|
||||
metadata/pv_map.c \
|
||||
metadata/raid_manip.c \
|
||||
|
@@ -29,7 +29,6 @@
|
||||
#include "lib/metadata/segtype.h"
|
||||
#include "lib/misc/sharedlib.h"
|
||||
#include "lib/metadata/metadata.h"
|
||||
#include "lib/misc/lvm-signal.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
@@ -178,22 +177,6 @@ int lv_passes_auto_activation_filter(struct cmd_context *cmd, struct logical_vol
|
||||
return _lv_passes_volumes_filter(cmd, lv, cn, activation_auto_activation_volume_list_CFG);
|
||||
}
|
||||
|
||||
static int _passes_readonly_filter(struct cmd_context *cmd,
|
||||
const struct logical_volume *lv)
|
||||
{
|
||||
const struct dm_config_node *cn;
|
||||
|
||||
if (!(cn = find_config_tree_array(cmd, activation_read_only_volume_list_CFG, NULL)))
|
||||
return 0;
|
||||
|
||||
return _lv_passes_volumes_filter(cmd, lv, cn, activation_read_only_volume_list_CFG);
|
||||
}
|
||||
|
||||
int lv_passes_readonly_filter(const struct logical_volume *lv)
|
||||
{
|
||||
return _passes_readonly_filter(lv->vg->cmd, lv);
|
||||
}
|
||||
|
||||
#ifndef DEVMAPPER_SUPPORT
|
||||
void set_activation(int act, int silent)
|
||||
{
|
||||
@@ -202,8 +185,8 @@ void set_activation(int act, int silent)
|
||||
if (warned || !act)
|
||||
return;
|
||||
|
||||
log_warn("WARNING: Compiled without libdevmapper support. "
|
||||
"Can't enable activation.");
|
||||
log_error("Compiled without libdevmapper support. "
|
||||
"Can't enable activation.");
|
||||
|
||||
warned = 1;
|
||||
}
|
||||
@@ -238,13 +221,23 @@ int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_la
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_info_with_seg_status(struct cmd_context *cmd,
|
||||
const struct lv_segment *lv_seg,
|
||||
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
|
||||
struct lvinfo *info, int with_open_count, int with_read_ahead)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume *lv,
|
||||
const struct lv_segment *lv_seg, int use_layer,
|
||||
struct lv_with_info_and_seg_status *status,
|
||||
int with_open_count, int with_read_ahead)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_status(struct cmd_context *cmd, const struct lv_segment *lv_seg,
|
||||
int use_layer, struct lv_seg_status *lv_seg_status)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_cache_status(const struct logical_volume *cache_lv,
|
||||
struct lv_status_cache **status)
|
||||
{
|
||||
@@ -291,21 +284,18 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_raid_status(const struct logical_volume *lv, struct lv_status_raid **status)
|
||||
int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
|
||||
dm_percent_t *percent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_writecache_message(const struct logical_volume *lv, const char *msg)
|
||||
int lv_thin_percent(const struct logical_volume *lv, int mapped,
|
||||
dm_percent_t *percent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_thin_pool_status(const struct logical_volume *lv, int flush,
|
||||
struct lv_status_thin_pool **thin_pool_status)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_thin_status(const struct logical_volume *lv, int flush,
|
||||
struct lv_status_thin **thin_status)
|
||||
int lv_thin_pool_transaction_id(const struct logical_volume *lv,
|
||||
uint64_t *transaction_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -313,15 +303,6 @@ int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_vdo_pool_status(const struct logical_volume *lv, int flush,
|
||||
struct lv_status_vdo **vdo_status)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_vdo_pool_percent(const struct logical_volume *lv, dm_percent_t *percent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lvs_in_vg_activated(const struct volume_group *vg)
|
||||
{
|
||||
return 0;
|
||||
@@ -413,7 +394,7 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int device_is_usable(struct device *dev, struct dev_usable_check_params check, int *is_lv)
|
||||
int device_is_usable(struct device *dev, struct dev_usable_check_params check)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -476,6 +457,17 @@ static int _passes_activation_filter(struct cmd_context *cmd,
|
||||
return _lv_passes_volumes_filter(cmd, lv, cn, activation_volume_list_CFG);
|
||||
}
|
||||
|
||||
static int _passes_readonly_filter(struct cmd_context *cmd,
|
||||
const struct logical_volume *lv)
|
||||
{
|
||||
const struct dm_config_node *cn;
|
||||
|
||||
if (!(cn = find_config_tree_array(cmd, activation_read_only_volume_list_CFG, NULL)))
|
||||
return 0;
|
||||
|
||||
return _lv_passes_volumes_filter(cmd, lv, cn, activation_read_only_volume_list_CFG);
|
||||
}
|
||||
|
||||
int library_version(char *version, size_t size)
|
||||
{
|
||||
if (!activation())
|
||||
@@ -833,15 +825,12 @@ int lv_info_with_seg_status(struct cmd_context *cmd,
|
||||
#define OPEN_COUNT_CHECK_USLEEP_DELAY 200000
|
||||
|
||||
/* Only report error if error_if_used is set */
|
||||
/* Returns 0 if in use, 1 if it is unused, 2 when it is not present in table */
|
||||
int lv_check_not_in_use(const struct logical_volume *lv, int error_if_used)
|
||||
{
|
||||
struct lvinfo info;
|
||||
unsigned int open_count_check_retries;
|
||||
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) || !info.exists)
|
||||
return 2;
|
||||
else if (!info.open_count)
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) || !info.exists || !info.open_count)
|
||||
return 1;
|
||||
|
||||
/* If sysfs is not used, use open_count information only. */
|
||||
@@ -868,24 +857,25 @@ int lv_check_not_in_use(const struct logical_volume *lv, int error_if_used)
|
||||
}
|
||||
|
||||
open_count_check_retries = retry_deactivation() ? OPEN_COUNT_CHECK_RETRIES : 1;
|
||||
while (open_count_check_retries--) {
|
||||
if (interruptible_usleep(OPEN_COUNT_CHECK_USLEEP_DELAY))
|
||||
break; /* interrupted */
|
||||
while (info.open_count > 0 && open_count_check_retries--) {
|
||||
if (!open_count_check_retries) {
|
||||
if (error_if_used)
|
||||
log_error("Logical volume %s in use.", display_lvname(lv));
|
||||
else
|
||||
log_debug_activation("Logical volume %s in use.", display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
usleep(OPEN_COUNT_CHECK_USLEEP_DELAY);
|
||||
log_debug_activation("Retrying open_count check for %s.",
|
||||
display_lvname(lv));
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) || !info.exists) {
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0)) {
|
||||
stack; /* device dissappeared? */
|
||||
return 1;
|
||||
} else if (!info.open_count)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (error_if_used)
|
||||
log_error("Logical volume %s in use.", display_lvname(lv));
|
||||
else
|
||||
log_debug_activation("Logical volume %s in use.", display_lvname(lv));
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -976,28 +966,35 @@ int lv_raid_percent(const struct logical_volume *lv, dm_percent_t *percent)
|
||||
|
||||
int lv_raid_data_offset(const struct logical_volume *lv, uint64_t *data_offset)
|
||||
{
|
||||
struct lv_status_raid *raid_status;
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
struct dm_status_raid *status;
|
||||
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking raid data offset and dev sectors for LV %s/%s",
|
||||
lv->vg->name, lv->name);
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
|
||||
if (!lv_raid_status(lv, &raid_status))
|
||||
return_0;
|
||||
if (!(r = dev_manager_raid_status(dm, lv, &status))) {
|
||||
dev_manager_destroy(dm);
|
||||
return_0;
|
||||
}
|
||||
|
||||
*data_offset = raid_status->raid->data_offset;
|
||||
*data_offset = status->data_offset;
|
||||
|
||||
dm_pool_destroy(raid_status->mem);
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
|
||||
{
|
||||
int r = 1;
|
||||
struct lv_status_raid *raid_status;
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
struct dm_status_raid *status;
|
||||
|
||||
*dev_health = NULL;
|
||||
|
||||
@@ -1007,23 +1004,25 @@ int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
|
||||
log_debug_activation("Checking raid device health for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!lv_raid_status(lv, &raid_status))
|
||||
return_0;
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
|
||||
if (!(*dev_health = dm_pool_strdup(lv->vg->cmd->mem,
|
||||
raid_status->raid->dev_health))) {
|
||||
stack;
|
||||
r = 0;
|
||||
if (!(r = dev_manager_raid_status(dm, lv, &status)) ||
|
||||
!(*dev_health = dm_pool_strdup(lv->vg->cmd->mem,
|
||||
status->dev_health))) {
|
||||
dev_manager_destroy(dm);
|
||||
return_0;
|
||||
}
|
||||
|
||||
dm_pool_destroy(raid_status->mem);
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt)
|
||||
{
|
||||
struct lv_status_raid *raid_status;
|
||||
struct dev_manager *dm;
|
||||
struct dm_status_raid *status;
|
||||
|
||||
*dev_cnt = 0;
|
||||
|
||||
@@ -1032,20 +1031,24 @@ int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt)
|
||||
|
||||
log_debug_activation("Checking raid device count for LV %s/%s",
|
||||
lv->vg->name, lv->name);
|
||||
|
||||
if (!lv_raid_status(lv, &raid_status))
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
|
||||
*dev_cnt = raid_status->raid->dev_count;
|
||||
if (!dev_manager_raid_status(dm, lv, &status)) {
|
||||
dev_manager_destroy(dm);
|
||||
return_0;
|
||||
}
|
||||
*dev_cnt = status->dev_count;
|
||||
|
||||
dm_pool_destroy(raid_status->mem);
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
|
||||
{
|
||||
struct lv_status_raid *raid_status;
|
||||
struct dev_manager *dm;
|
||||
struct dm_status_raid *status;
|
||||
|
||||
*cnt = 0;
|
||||
|
||||
@@ -1055,20 +1058,25 @@ int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
|
||||
log_debug_activation("Checking raid mismatch count for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!lv_raid_status(lv, &raid_status))
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
|
||||
*cnt = raid_status->raid->mismatch_count;
|
||||
if (!dev_manager_raid_status(dm, lv, &status)) {
|
||||
dev_manager_destroy(dm);
|
||||
return_0;
|
||||
}
|
||||
*cnt = status->mismatch_count;
|
||||
|
||||
dm_pool_destroy(raid_status->mem);
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action)
|
||||
{
|
||||
struct lv_status_raid *raid_status;
|
||||
int r = 1;
|
||||
struct dev_manager *dm;
|
||||
struct dm_status_raid *status;
|
||||
char *action;
|
||||
|
||||
*sync_action = NULL;
|
||||
|
||||
@@ -1078,27 +1086,30 @@ int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action)
|
||||
log_debug_activation("Checking raid sync_action for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!lv_raid_status(lv, &raid_status))
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
|
||||
/* status->sync_action can be NULL if dm-raid version < 1.5.0 */
|
||||
if (!raid_status->raid->sync_action ||
|
||||
!(*sync_action = dm_pool_strdup(lv->vg->cmd->mem,
|
||||
raid_status->raid->sync_action))) {
|
||||
stack;
|
||||
r = 0;
|
||||
if (!dev_manager_raid_status(dm, lv, &status) ||
|
||||
!status->sync_action ||
|
||||
!(action = dm_pool_strdup(lv->vg->cmd->mem,
|
||||
status->sync_action))) {
|
||||
dev_manager_destroy(dm);
|
||||
return_0;
|
||||
}
|
||||
|
||||
dm_pool_destroy(raid_status->mem);
|
||||
*sync_action = action;
|
||||
|
||||
return r;
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lv_raid_message(const struct logical_volume *lv, const char *msg)
|
||||
{
|
||||
struct lv_status_raid *raid_status;
|
||||
struct dev_manager *dm = NULL;
|
||||
int r = 0;
|
||||
struct dev_manager *dm;
|
||||
struct dm_status_raid *status;
|
||||
|
||||
if (!seg_is_raid(first_seg(lv))) {
|
||||
/*
|
||||
@@ -1123,10 +1134,16 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lv_raid_status(lv, &raid_status))
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
|
||||
if (!raid_status->raid->sync_action) {
|
||||
if (!(r = dev_manager_raid_status(dm, lv, &status))) {
|
||||
log_error("Failed to retrieve status of %s.",
|
||||
display_lvname(lv));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!status->sync_action) {
|
||||
log_error("Kernel driver does not support this action: %s", msg);
|
||||
goto out;
|
||||
}
|
||||
@@ -1148,43 +1165,19 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
|
||||
log_error("\"%s\" is not a supported sync operation.", msg);
|
||||
goto out;
|
||||
}
|
||||
if (strcmp(raid_status->raid->sync_action, "idle")) {
|
||||
if (strcmp(status->sync_action, "idle")) {
|
||||
log_error("%s state is currently \"%s\". Unable to switch to \"%s\".",
|
||||
display_lvname(lv), raid_status->raid->sync_action, msg);
|
||||
display_lvname(lv), status->sync_action, msg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
|
||||
r = dev_manager_raid_message(dm, lv, msg);
|
||||
out:
|
||||
if (dm)
|
||||
dev_manager_destroy(dm);
|
||||
dm_pool_destroy(raid_status->mem);
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int lv_raid_status(const struct logical_volume *lv, struct lv_status_raid **status)
|
||||
{
|
||||
struct dev_manager *dm;
|
||||
int exists;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
|
||||
if (!dev_manager_raid_status(dm, lv, status, &exists)) {
|
||||
dev_manager_destroy(dm);
|
||||
if (exists)
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
/* User has to call dm_pool_destroy(status->mem)! */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lv_writecache_message(const struct logical_volume *lv, const char *msg)
|
||||
{
|
||||
int r = 0;
|
||||
@@ -1217,7 +1210,6 @@ int lv_cache_status(const struct logical_volume *cache_lv,
|
||||
{
|
||||
struct dev_manager *dm;
|
||||
struct lv_segment *cache_seg;
|
||||
int exists;
|
||||
|
||||
if (lv_is_cache_pool(cache_lv)) {
|
||||
if (dm_list_empty(&cache_lv->segs_using_this_lv) ||
|
||||
@@ -1235,74 +1227,125 @@ int lv_cache_status(const struct logical_volume *cache_lv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lv_info(cache_lv->vg->cmd, cache_lv, 1, NULL, 0, 0)) {
|
||||
log_error("Cannot check status for locally inactive cache volume %s.",
|
||||
display_lvname(cache_lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug_activation("Checking status for cache volume %s.",
|
||||
display_lvname(cache_lv));
|
||||
|
||||
if (!(dm = dev_manager_create(cache_lv->vg->cmd, cache_lv->vg->name, 1)))
|
||||
return_0;
|
||||
|
||||
if (!dev_manager_cache_status(dm, cache_lv, status, &exists)) {
|
||||
if (!dev_manager_cache_status(dm, cache_lv, status)) {
|
||||
dev_manager_destroy(dm);
|
||||
if (exists)
|
||||
stack;
|
||||
return 0;
|
||||
return_0;
|
||||
}
|
||||
/* User has to call dm_pool_destroy(status->mem)! */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lv_thin_pool_status(const struct logical_volume *lv, int flush,
|
||||
struct lv_status_thin_pool **thin_pool_status)
|
||||
/*
|
||||
* Returns data or metadata percent usage, depends on metadata 0/1.
|
||||
* Returns 1 if percent set, else 0 on failure.
|
||||
*/
|
||||
int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
|
||||
dm_percent_t *percent)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
int exists;
|
||||
|
||||
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking thin %sdata percent for LV %s.",
|
||||
(metadata) ? "meta" : "", display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
|
||||
if (!dev_manager_thin_pool_status(dm, lv, flush, thin_pool_status, &exists)) {
|
||||
dev_manager_destroy(dm);
|
||||
if (exists)
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(r = dev_manager_thin_pool_percent(dm, lv, metadata, percent)))
|
||||
stack;
|
||||
|
||||
/* User has to call dm_pool_destroy(thin_pool_status->mem)! */
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
int lv_thin_status(const struct logical_volume *lv, int flush,
|
||||
struct lv_status_thin **thin_status)
|
||||
/*
|
||||
* Returns 1 if percent set, else 0 on failure.
|
||||
*/
|
||||
int lv_thin_percent(const struct logical_volume *lv,
|
||||
int mapped, dm_percent_t *percent)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
int exists;
|
||||
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking thin percent for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
|
||||
if (!dev_manager_thin_status(dm, lv, flush, thin_status, &exists)) {
|
||||
dev_manager_destroy(dm);
|
||||
if (exists)
|
||||
stack;
|
||||
if (!(r = dev_manager_thin_percent(dm, lv, mapped, percent)))
|
||||
stack;
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if transaction_id set, else 0 on failure.
|
||||
*/
|
||||
int lv_thin_pool_transaction_id(const struct logical_volume *lv,
|
||||
uint64_t *transaction_id)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
struct dm_status_thin_pool *status;
|
||||
|
||||
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* User has to call dm_pool_destroy(thin_status->mem)! */
|
||||
log_debug_activation("Checking thin-pool transaction id for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
return 1;
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_thin_pool_status(dm, lv, &status, 0)))
|
||||
stack;
|
||||
else
|
||||
*transaction_id = status->transaction_id;
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id)
|
||||
{
|
||||
struct dev_manager *dm;
|
||||
int exists;
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking device id for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_thin_device_id(dm, lv, device_id, &exists)))
|
||||
if (exists)
|
||||
stack;
|
||||
if (!(r = dev_manager_thin_device_id(dm, lv, device_id)))
|
||||
stack;
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
@@ -1319,22 +1362,28 @@ int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id)
|
||||
int lv_vdo_pool_status(const struct logical_volume *lv, int flush,
|
||||
struct lv_status_vdo **vdo_status)
|
||||
{
|
||||
int r = 0;
|
||||
struct dev_manager *dm;
|
||||
int exists;
|
||||
|
||||
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking VDO pool status for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, !lv_is_pvmove(lv))))
|
||||
return_0;
|
||||
|
||||
if (!dev_manager_vdo_pool_status(dm, lv, flush, vdo_status, &exists)) {
|
||||
dev_manager_destroy(dm);
|
||||
if (exists)
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!dev_manager_vdo_pool_status(dm, lv, vdo_status, flush))
|
||||
goto_out;
|
||||
|
||||
/* User has to call dm_pool_destroy(vdo_status->mem) */
|
||||
r = 1;
|
||||
out:
|
||||
if (!r)
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
int lv_vdo_pool_percent(const struct logical_volume *lv, dm_percent_t *percent)
|
||||
@@ -2030,6 +2079,12 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
if (!activation())
|
||||
return 1;
|
||||
|
||||
/* Ignore origin_only unless LV is origin in both old and new metadata */
|
||||
/* or LV is thin or thin pool volume */
|
||||
if (!lv_is_thin_volume(lv) && !lv_is_thin_pool(lv) &&
|
||||
!(lv_is_origin(lv) && lv_is_origin(lv_pre)))
|
||||
laopts->origin_only = 0;
|
||||
|
||||
if (test_mode()) {
|
||||
_skip("Suspending %s%s.", display_lvname(lv),
|
||||
laopts->origin_only ? " origin without snapshots" : "");
|
||||
@@ -2051,12 +2106,6 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
|
||||
lv_calculate_readahead(lv, NULL);
|
||||
|
||||
/* Ignore origin_only unless LV is origin in both old and new metadata */
|
||||
/* or LV is thin or thin pool volume */
|
||||
if (!lv_is_thin_volume(lv) && !lv_is_thin_pool(lv) &&
|
||||
!(lv_is_origin(lv) && lv_is_origin(lv_pre)))
|
||||
laopts->origin_only = 0;
|
||||
|
||||
/*
|
||||
* Preload devices for the LV.
|
||||
* If the PVMOVE LV is being removed, it's only present in the old
|
||||
@@ -2148,6 +2197,8 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
if (laopts->origin_only && lv_is_thin_volume(lv) && lv_is_thin_volume(lv_pre))
|
||||
lockfs = 1;
|
||||
|
||||
critical_section_inc(cmd, "suspending");
|
||||
|
||||
if (!lv_is_locked(lv) && lv_is_locked(lv_pre) &&
|
||||
(pvmove_lv = find_pvmove_lv_in_lv(lv_pre))) {
|
||||
/*
|
||||
@@ -2189,23 +2240,16 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
}
|
||||
dm_list_add(&suspend_lvs, &lvl->list);
|
||||
}
|
||||
|
||||
critical_section_inc(cmd, "suspending");
|
||||
|
||||
dm_list_iterate_items(lvl, &suspend_lvs)
|
||||
if (!_lv_suspend_lv(lvl->lv, laopts, lockfs, 1)) {
|
||||
critical_section_dec(cmd, "failed suspend");
|
||||
goto_out; /* FIXME: resume on recovery path? */
|
||||
}
|
||||
|
||||
} else { /* Standard suspend */
|
||||
critical_section_inc(cmd, "suspending");
|
||||
|
||||
} else /* Standard suspend */
|
||||
if (!_lv_suspend_lv(lv, laopts, lockfs, flush_required)) {
|
||||
critical_section_dec(cmd, "failed suspend");
|
||||
goto_out;
|
||||
}
|
||||
}
|
||||
|
||||
r = 1;
|
||||
out:
|
||||
@@ -2225,8 +2269,8 @@ int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned o
|
||||
const struct logical_volume *lv, const struct logical_volume *lv_pre)
|
||||
{
|
||||
struct lv_activate_opts laopts = {
|
||||
.exclusive = exclusive,
|
||||
.origin_only = origin_only
|
||||
.origin_only = origin_only,
|
||||
.exclusive = exclusive
|
||||
};
|
||||
|
||||
return _lv_suspend(cmd, lvid_s, &laopts, 0, lv, lv_pre);
|
||||
@@ -2278,9 +2322,6 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
|
||||
lv_is_thin_volume(lv) ? " thin only" : " without snapshots") : "",
|
||||
laopts->revert ? " (reverting)" : "");
|
||||
|
||||
if (laopts->revert)
|
||||
goto needs_resume;
|
||||
|
||||
if (!lv_info(cmd, lv, laopts->origin_only, &info, 0, 0))
|
||||
goto_out;
|
||||
|
||||
@@ -2340,8 +2381,8 @@ int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
|
||||
unsigned revert, const struct logical_volume *lv)
|
||||
{
|
||||
struct lv_activate_opts laopts = {
|
||||
.exclusive = exclusive,
|
||||
.origin_only = origin_only,
|
||||
.exclusive = exclusive,
|
||||
.revert = revert
|
||||
};
|
||||
|
||||
@@ -2390,47 +2431,44 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logi
|
||||
|
||||
log_debug_activation("Deactivating %s.", display_lvname(lv));
|
||||
|
||||
if (!lv_info(cmd, lv, 0, &info, 0, 0))
|
||||
goto_out;
|
||||
|
||||
if (!info.exists) {
|
||||
r = 1;
|
||||
/* Check attached snapshot segments are also inactive */
|
||||
dm_list_iterate(snh, &lv->snapshot_segs) {
|
||||
if (!lv_info(cmd, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow,
|
||||
0, &info, 0, 0))
|
||||
goto_out;
|
||||
if (info.exists) {
|
||||
r = 0; /* Snapshot left in table? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lv_is_vdo_pool(lv)) {
|
||||
/* If someone has remove 'linear' mapping over VDO device
|
||||
* we may still be able to deactivate the rest of the tree
|
||||
* i.e. in test-suite we simulate this via 'dmsetup remove' */
|
||||
if (!lv_info(cmd, lv, 1, &info, 1, 0))
|
||||
goto_out;
|
||||
|
||||
if (info.exists && !info.open_count)
|
||||
r = 0; /* Unused VDO device left in table? */
|
||||
}
|
||||
|
||||
if (r)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (lv_is_visible(lv) || lv_is_virtual_origin(lv) ||
|
||||
lv_is_merging_thin_snapshot(lv)) {
|
||||
switch (lv_check_not_in_use(lv, 1)) {
|
||||
case 0: goto_out;
|
||||
case 2: goto no_exists;
|
||||
}
|
||||
if (!lv_check_not_in_use(lv, 1))
|
||||
goto_out;
|
||||
|
||||
if (lv_is_origin(lv) && _lv_has_open_snapshots(lv))
|
||||
goto_out;
|
||||
} else {
|
||||
if (!lv_info(cmd, lv, 0, &info, 0, 0))
|
||||
goto_out;
|
||||
|
||||
if (!info.exists) {
|
||||
no_exists:
|
||||
r = 1;
|
||||
/* Check attached snapshot segments are also inactive */
|
||||
dm_list_iterate(snh, &lv->snapshot_segs) {
|
||||
if (!lv_info(cmd, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow,
|
||||
0, &info, 0, 0))
|
||||
goto_out;
|
||||
if (info.exists) {
|
||||
r = 0; /* Snapshot left in table? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lv_is_vdo_pool(lv)) {
|
||||
/* If someone has remove 'linear' mapping over VDO device
|
||||
* we may still be able to deactivate the rest of the tree
|
||||
* i.e. in test-suite we simulate this via 'dmsetup remove' */
|
||||
if (!lv_info(cmd, lv, 1, &info, 1, 0))
|
||||
goto_out;
|
||||
|
||||
if (info.exists && !info.open_count)
|
||||
r = 0; /* Unused VDO device left in table? */
|
||||
}
|
||||
|
||||
if (r)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!monitor_dev_for_events(cmd, lv, &laopts, 0))
|
||||
@@ -2497,13 +2535,6 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((cmd->partial_activation || cmd->degraded_activation) &&
|
||||
lv_is_partial(lv) && lv_is_raid(lv) && lv_raid_has_integrity((struct logical_volume *)lv)) {
|
||||
cmd->partial_activation = 0;
|
||||
cmd->degraded_activation = 0;
|
||||
log_print("No degraded or partial activation for raid with integrity.");
|
||||
}
|
||||
|
||||
if ((!lv->vg->cmd->partial_activation) && lv_is_partial(lv)) {
|
||||
if (!lv_is_raid_type(lv) || !partial_raid_lv_supports_degraded_activation(lv)) {
|
||||
log_error("Refusing activation of partial LV %s. "
|
||||
@@ -2520,14 +2551,6 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
||||
}
|
||||
}
|
||||
|
||||
if ((cmd->partial_activation || cmd->degraded_activation) && lv_is_writecache(lv)) {
|
||||
struct logical_volume *lv_fast = first_seg(lv)->writecache;
|
||||
if (lv_is_partial(lv) || (lv_fast && lv_is_partial(lv_fast))) {
|
||||
log_error("Cannot use partial or degraded activation with writecache.");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (lv_has_unknown_segments(lv)) {
|
||||
log_error("Refusing activation of LV %s containing "
|
||||
"an unrecognised segment.", display_lvname(lv));
|
||||
@@ -2827,7 +2850,7 @@ static int _deactivate_sub_lv_cb(struct logical_volume *lv, void *data)
|
||||
*/
|
||||
int deactivate_lv_with_sub_lv(const struct logical_volume *lv)
|
||||
{
|
||||
struct logical_volume *flv = NULL;
|
||||
struct logical_volume *flv;
|
||||
|
||||
if (!deactivate_lv(lv->vg->cmd, lv)) {
|
||||
log_error("Cannot deactivate logical volume %s.",
|
||||
@@ -2837,7 +2860,7 @@ int deactivate_lv_with_sub_lv(const struct logical_volume *lv)
|
||||
|
||||
if (!for_each_sub_lv((struct logical_volume *)lv, _deactivate_sub_lv_cb, &flv)) {
|
||||
log_error("Cannot deactivate subvolume %s of logical volume %s.",
|
||||
(flv) ? display_lvname(flv) : "", display_lvname(lv));
|
||||
display_lvname(flv), display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2932,7 +2955,8 @@ int revert_lv(struct cmd_context *cmd, const struct logical_volume *lv)
|
||||
|
||||
ret = lv_resume_if_active(cmd, NULL, 0, 0, 1, lv_committed(lv));
|
||||
|
||||
critical_section_dec(cmd, "unlocking on revert");
|
||||
critical_section_dec(cmd, "unlocking on resume");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,6 @@ typedef enum {
|
||||
SEG_STATUS_THIN_POOL,
|
||||
SEG_STATUS_VDO_POOL,
|
||||
SEG_STATUS_WRITECACHE,
|
||||
SEG_STATUS_INTEGRITY,
|
||||
SEG_STATUS_UNKNOWN
|
||||
} lv_seg_status_type_t;
|
||||
|
||||
@@ -54,7 +53,6 @@ struct lv_seg_status {
|
||||
struct dm_status_thin *thin;
|
||||
struct dm_status_thin_pool *thin_pool;
|
||||
struct dm_status_writecache *writecache;
|
||||
struct dm_status_integrity *integrity;
|
||||
struct lv_status_vdo vdo_pool;
|
||||
};
|
||||
};
|
||||
@@ -188,15 +186,16 @@ int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health);
|
||||
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt);
|
||||
int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action);
|
||||
int lv_raid_message(const struct logical_volume *lv, const char *msg);
|
||||
int lv_raid_status(const struct logical_volume *lv, struct lv_status_raid **status);
|
||||
int lv_writecache_message(const struct logical_volume *lv, const char *msg);
|
||||
int lv_cache_status(const struct logical_volume *cache_lv,
|
||||
struct lv_status_cache **status);
|
||||
int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
|
||||
dm_percent_t *percent);
|
||||
int lv_thin_percent(const struct logical_volume *lv, int mapped,
|
||||
dm_percent_t *percent);
|
||||
int lv_thin_pool_transaction_id(const struct logical_volume *lv,
|
||||
uint64_t *transaction_id);
|
||||
int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id);
|
||||
int lv_thin_status(const struct logical_volume *lv, int flush,
|
||||
struct lv_status_thin **status);
|
||||
int lv_thin_pool_status(const struct logical_volume *lv, int flush,
|
||||
struct lv_status_thin_pool **status);
|
||||
int lv_vdo_pool_status(const struct logical_volume *lv, int flush,
|
||||
struct lv_status_vdo **status);
|
||||
int lv_vdo_pool_percent(const struct logical_volume *lv, dm_percent_t *percent);
|
||||
@@ -209,8 +208,6 @@ int lvs_in_vg_opened(const struct volume_group *vg);
|
||||
|
||||
int lv_is_active(const struct logical_volume *lv);
|
||||
|
||||
int lv_passes_readonly_filter(const struct logical_volume *lv);
|
||||
|
||||
/* Check is any component LV is active */
|
||||
const struct logical_volume *lv_component_is_active(const struct logical_volume *lv);
|
||||
const struct logical_volume *lv_holder_is_active(const struct logical_volume *lv);
|
||||
@@ -254,7 +251,7 @@ struct dev_usable_check_params {
|
||||
* Returns 1 if mapped device is not suspended, blocked or
|
||||
* is using a reserved name.
|
||||
*/
|
||||
int device_is_usable(struct device *dev, struct dev_usable_check_params check, int *is_lv);
|
||||
int device_is_usable(struct device *dev, struct dev_usable_check_params check);
|
||||
|
||||
/*
|
||||
* Declaration moved here from fs.h to keep header fs.h hidden
|
||||
@@ -263,7 +260,6 @@ void fs_unlock(void);
|
||||
|
||||
#define TARGET_NAME_CACHE "cache"
|
||||
#define TARGET_NAME_WRITECACHE "writecache"
|
||||
#define TARGET_NAME_INTEGRITY "integrity"
|
||||
#define TARGET_NAME_ERROR "error"
|
||||
#define TARGET_NAME_ERROR_OLD "erro" /* Truncated in older kernels */
|
||||
#define TARGET_NAME_LINEAR "linear"
|
||||
@@ -281,7 +277,6 @@ void fs_unlock(void);
|
||||
#define MODULE_NAME_CLUSTERED_MIRROR "clog"
|
||||
#define MODULE_NAME_CACHE TARGET_NAME_CACHE
|
||||
#define MODULE_NAME_WRITECACHE TARGET_NAME_WRITECACHE
|
||||
#define MODULE_NAME_INTEGRITY TARGET_NAME_INTEGRITY
|
||||
#define MODULE_NAME_ERROR TARGET_NAME_ERROR
|
||||
#define MODULE_NAME_LOG_CLUSTERED "log-clustered"
|
||||
#define MODULE_NAME_LOG_USERSPACE "log-userspace"
|
||||
|
@@ -26,7 +26,6 @@
|
||||
#include "lib/activate/activate.h"
|
||||
#include "lib/misc/lvm-exec.h"
|
||||
#include "lib/datastruct/str_list.h"
|
||||
#include "lib/misc/lvm-signal.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <dirent.h>
|
||||
@@ -47,7 +46,7 @@ typedef enum {
|
||||
} action_t;
|
||||
|
||||
/* This list must match lib/misc/lvm-string.c:build_dm_uuid(). */
|
||||
const char *uuid_suffix_list[] = { "pool", "cdata", "cmeta", "cvol", "tdata", "tmeta", "vdata", "vpool", "imeta", NULL};
|
||||
const char *uuid_suffix_list[] = { "pool", "cdata", "cmeta", "cvol", "tdata", "tmeta", "vdata", "vpool", NULL};
|
||||
|
||||
struct dlid_list {
|
||||
struct dm_list list;
|
||||
@@ -87,7 +86,7 @@ int read_only_lv(const struct logical_volume *lv, const struct lv_activate_opts
|
||||
return 0; /* Keep RAID SubLvs writable */
|
||||
|
||||
if (!layer) {
|
||||
if (lv_is_thin_pool(lv) || lv_is_vdo_pool(lv))
|
||||
if (lv_is_thin_pool(lv))
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -223,10 +222,6 @@ static int _get_segment_status_from_target_params(const char *target_name,
|
||||
if (!dm_get_status_writecache(seg_status->mem, params, &(seg_status->writecache)))
|
||||
return_0;
|
||||
seg_status->type = SEG_STATUS_WRITECACHE;
|
||||
} else if (segtype_is_integrity(segtype)) {
|
||||
if (!dm_get_status_integrity(seg_status->mem, params, &(seg_status->integrity)))
|
||||
return_0;
|
||||
seg_status->type = SEG_STATUS_INTEGRITY;
|
||||
} else
|
||||
/*
|
||||
* TODO: Add support for other segment types too!
|
||||
@@ -262,7 +257,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
|
||||
int dmtask;
|
||||
int with_flush; /* TODO: arg for _info_run */
|
||||
void *target = NULL;
|
||||
uint64_t target_start, target_length, start, length, length_crop = 0;
|
||||
uint64_t target_start, target_length, start, length;
|
||||
char *target_name, *target_params;
|
||||
const char *devname;
|
||||
|
||||
@@ -298,22 +293,17 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
|
||||
/* Uses max DM_THIN_MAX_METADATA_SIZE sectors for metadata device */
|
||||
if (lv_is_thin_pool_metadata(seg_status->seg->lv) &&
|
||||
(length > DM_THIN_MAX_METADATA_SIZE))
|
||||
length_crop = DM_THIN_MAX_METADATA_SIZE;
|
||||
length = DM_THIN_MAX_METADATA_SIZE;
|
||||
|
||||
/* Uses virtual size with headers for VDO pool device */
|
||||
if (lv_is_vdo_pool(seg_status->seg->lv))
|
||||
length = get_vdo_pool_virtual_size(seg_status->seg);
|
||||
|
||||
if (lv_is_integrity(seg_status->seg->lv))
|
||||
length = seg_status->seg->integrity_data_sectors;
|
||||
|
||||
do {
|
||||
target = dm_get_next_target(dmt, target, &target_start,
|
||||
&target_length, &target_name, &target_params);
|
||||
|
||||
if ((start == target_start) &&
|
||||
((length == target_length) ||
|
||||
(length_crop && (length_crop == target_length))))
|
||||
if ((start == target_start) && (length == target_length))
|
||||
break; /* Keep target_params when matching segment is found */
|
||||
|
||||
target_params = NULL; /* Marking this target_params unusable */
|
||||
@@ -406,7 +396,7 @@ static int _ignore_blocked_mirror_devices(struct device *dev,
|
||||
.check_blocked = 1,
|
||||
.check_suspended = ignore_suspended_devices(),
|
||||
.check_error_target = 1,
|
||||
.check_reserved = 0 }, NULL))
|
||||
.check_reserved = 0 }))
|
||||
goto out; /* safe to use */
|
||||
stack;
|
||||
}
|
||||
@@ -621,17 +611,16 @@ static int _ignore_frozen_raid(struct device *dev, const char *params)
|
||||
*
|
||||
* Returns: 1 if usable, 0 otherwise
|
||||
*/
|
||||
int device_is_usable(struct device *dev, struct dev_usable_check_params check, int *is_lv)
|
||||
int device_is_usable(struct device *dev, struct dev_usable_check_params check)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
struct dm_info info;
|
||||
const char *name, *uuid;
|
||||
uint64_t start, length;
|
||||
char *target_type = NULL;
|
||||
char *params, *vgname, *lvname, *layer;
|
||||
char vg_name[NAME_LEN];
|
||||
char *params, *vgname = NULL, *lvname, *layer;
|
||||
void *next = NULL;
|
||||
int only_error_or_zero_target = 1;
|
||||
int only_error_target = 1;
|
||||
int r = 0;
|
||||
|
||||
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, NULL, NULL,
|
||||
@@ -654,49 +643,42 @@ int device_is_usable(struct device *dev, struct dev_usable_check_params check, i
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (uuid && (check.check_reserved || check.check_lv)) {
|
||||
if (!strncmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1)) { /* with LVM- prefix */
|
||||
if (check.check_reserved) {
|
||||
/* Check internal lvm devices */
|
||||
if (strlen(uuid) > (sizeof(UUID_PREFIX) + 2 * ID_LEN)) { /* 68 with suffix */
|
||||
log_debug_activation("%s: Reserved uuid %s on internal LV device %s not usable.",
|
||||
dev_name(dev), uuid, name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Recognize some older reserved LVs just from the LV name (snapshot, pvmove...) */
|
||||
vgname = vg_name;
|
||||
if (!dm_strncpy(vg_name, name, sizeof(vg_name)) ||
|
||||
!dm_split_lvm_name(NULL, NULL, &vgname, &lvname, &layer))
|
||||
goto_out;
|
||||
|
||||
/* FIXME: fails to handle dev aliases i.e. /dev/dm-5, replace with UUID suffix */
|
||||
if (lvname && (is_reserved_lvname(lvname) || *layer)) {
|
||||
log_debug_activation("%s: Reserved internal LV device %s/%s%s%s not usable.",
|
||||
dev_name(dev), vgname, lvname, *layer ? "-" : "", layer);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (check.check_lv) {
|
||||
/* Skip LVs */
|
||||
if (is_lv)
|
||||
*is_lv = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (check.check_reserved &&
|
||||
(!strncmp(uuid, CRYPT_TEMP, sizeof(CRYPT_TEMP) - 1) ||
|
||||
!strncmp(uuid, CRYPT_SUBDEV, sizeof(CRYPT_SUBDEV) - 1) ||
|
||||
!strncmp(uuid, STRATIS, sizeof(STRATIS) - 1))) {
|
||||
/* Skip private crypto devices */
|
||||
log_debug_activation("%s: Reserved uuid %s on %s device %s not usable.",
|
||||
dev_name(dev), uuid,
|
||||
uuid[0] == 'C' ? "crypto" : "stratis",
|
||||
name);
|
||||
/* Check internal lvm devices */
|
||||
if (check.check_reserved &&
|
||||
uuid && !strncmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1)) {
|
||||
if (strlen(uuid) > (sizeof(UUID_PREFIX) + 2 * ID_LEN)) { /* 68 */
|
||||
log_debug_activation("%s: Reserved uuid %s on internal LV device %s not usable.",
|
||||
dev_name(dev), uuid, name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(vgname = strdup(name)) ||
|
||||
!dm_split_lvm_name(NULL, NULL, &vgname, &lvname, &layer))
|
||||
goto_out;
|
||||
|
||||
/* FIXME: fails to handle dev aliases i.e. /dev/dm-5, replace with UUID suffix */
|
||||
if (lvname && (is_reserved_lvname(lvname) || *layer)) {
|
||||
log_debug_activation("%s: Reserved internal LV device %s/%s%s%s not usable.",
|
||||
dev_name(dev), vgname, lvname, *layer ? "-" : "", layer);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (check.check_lv && uuid && !strncmp(uuid, "LVM-", 4)) {
|
||||
/* Skip LVs */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (check.check_reserved && uuid &&
|
||||
(!strncmp(uuid, CRYPT_TEMP, sizeof(CRYPT_TEMP) - 1) ||
|
||||
!strncmp(uuid, CRYPT_SUBDEV, sizeof(CRYPT_SUBDEV) - 1) ||
|
||||
!strncmp(uuid, STRATIS, sizeof(STRATIS) - 1))) {
|
||||
/* Skip private crypto devices */
|
||||
log_debug_activation("%s: Reserved uuid %s on %s device %s not usable.",
|
||||
dev_name(dev), uuid,
|
||||
uuid[0] == 'C' ? "crypto" : "stratis",
|
||||
name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* FIXME Also check for mpath no paths */
|
||||
@@ -767,15 +749,13 @@ int device_is_usable(struct device *dev, struct dev_usable_check_params check, i
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (only_error_or_zero_target &&
|
||||
strcmp(target_type, TARGET_NAME_ERROR) &&
|
||||
strcmp(target_type, TARGET_NAME_ZERO))
|
||||
only_error_or_zero_target = 0;
|
||||
if (strcmp(target_type, TARGET_NAME_ERROR))
|
||||
only_error_target = 0;
|
||||
} while (next);
|
||||
|
||||
/* Skip devices consisting entirely of error or zero targets. */
|
||||
/* Skip devices consisting entirely of error targets. */
|
||||
/* FIXME Deal with device stacked above error targets? */
|
||||
if (check.check_error_target && only_error_or_zero_target) {
|
||||
if (check.check_error_target && only_error_target) {
|
||||
log_debug_activation("%s: Error device %s not usable.",
|
||||
dev_name(dev), name);
|
||||
goto out;
|
||||
@@ -786,6 +766,7 @@ int device_is_usable(struct device *dev, struct dev_usable_check_params check, i
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
free(vgname);
|
||||
dm_task_destroy(dmt);
|
||||
return r;
|
||||
}
|
||||
@@ -842,7 +823,8 @@ static int _info(struct cmd_context *cmd,
|
||||
if (strcmp(suffix_position + 1, suffix))
|
||||
continue;
|
||||
|
||||
(void) dm_strncpy(old_style_dlid, dlid, sizeof(old_style_dlid));
|
||||
(void) strncpy(old_style_dlid, dlid, sizeof(old_style_dlid));
|
||||
old_style_dlid[sizeof(old_style_dlid) - 1] = '\0';
|
||||
if (!_info_run(old_style_dlid, dminfo, read_ahead, seg_status,
|
||||
name_check, with_open_count, with_read_ahead,
|
||||
0, 0))
|
||||
@@ -1124,8 +1106,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
||||
const char *dlid,
|
||||
const char *target_type, int wait,
|
||||
const struct logical_volume *lv, dm_percent_t *overall_percent,
|
||||
uint32_t *event_nr, int fail_if_percent_unsupported,
|
||||
int *interrupted)
|
||||
uint32_t *event_nr, int fail_if_percent_unsupported)
|
||||
{
|
||||
int r = 0;
|
||||
struct dm_task *dmt;
|
||||
@@ -1146,12 +1127,9 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
||||
if (!(segtype = get_segtype_from_string(dm->cmd, target_type)))
|
||||
return_0;
|
||||
|
||||
if (wait)
|
||||
sigint_allow();
|
||||
|
||||
if (!(dmt = _setup_task_run(wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS, &info,
|
||||
name, dlid, event_nr, 0, 0, 0, 0, 0)))
|
||||
goto_bad;
|
||||
return_0;
|
||||
|
||||
if (!info.exists)
|
||||
goto_out;
|
||||
@@ -1219,19 +1197,8 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
||||
display_percent(dm->cmd, *overall_percent));
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
bad:
|
||||
if (wait) {
|
||||
sigint_restore();
|
||||
|
||||
if (sigint_caught()) {
|
||||
*interrupted = 1;
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1240,24 +1207,20 @@ static int _percent(struct dev_manager *dm, const char *name, const char *dlid,
|
||||
const struct logical_volume *lv, dm_percent_t *percent,
|
||||
uint32_t *event_nr, int fail_if_percent_unsupported)
|
||||
{
|
||||
int interrupted = 0;
|
||||
|
||||
if (dlid && *dlid) {
|
||||
if (_percent_run(dm, NULL, dlid, target_type, wait, lv, percent,
|
||||
event_nr, fail_if_percent_unsupported, &interrupted))
|
||||
event_nr, fail_if_percent_unsupported))
|
||||
return 1;
|
||||
|
||||
if (!interrupted &&
|
||||
_original_uuid_format_check_required(dm->cmd) &&
|
||||
if (_original_uuid_format_check_required(dm->cmd) &&
|
||||
_percent_run(dm, NULL, dlid + sizeof(UUID_PREFIX) - 1,
|
||||
target_type, wait, lv, percent,
|
||||
event_nr, fail_if_percent_unsupported, &interrupted))
|
||||
event_nr, fail_if_percent_unsupported))
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!interrupted && name &&
|
||||
_percent_run(dm, name, NULL, target_type, wait, lv, percent,
|
||||
event_nr, fail_if_percent_unsupported, &interrupted))
|
||||
if (name && _percent_run(dm, name, NULL, target_type, wait, lv, percent,
|
||||
event_nr, fail_if_percent_unsupported))
|
||||
return 1;
|
||||
|
||||
return_0;
|
||||
@@ -1459,7 +1422,7 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
|
||||
|
||||
int dev_manager_raid_status(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
struct lv_status_raid **status, int *exists)
|
||||
struct dm_status_raid **status)
|
||||
{
|
||||
int r = 0;
|
||||
const char *dlid;
|
||||
@@ -1469,11 +1432,6 @@ int dev_manager_raid_status(struct dev_manager *dm,
|
||||
char *type = NULL;
|
||||
char *params = NULL;
|
||||
const char *layer = lv_layer(lv);
|
||||
struct dm_status_raid *sr;
|
||||
|
||||
*exists = -1;
|
||||
if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_cache))))
|
||||
return_0;
|
||||
|
||||
if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
|
||||
return_0;
|
||||
@@ -1481,11 +1439,8 @@ int dev_manager_raid_status(struct dev_manager *dm,
|
||||
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, 0, 0)))
|
||||
return_0;
|
||||
|
||||
if (!(*exists = info.exists))
|
||||
goto out;
|
||||
|
||||
log_debug_activation("Checking raid status for volume %s.",
|
||||
display_lvname(lv));
|
||||
if (!info.exists)
|
||||
goto_out;
|
||||
|
||||
dm_get_next_target(dmt, NULL, &start, &length, &type, ¶ms);
|
||||
|
||||
@@ -1497,13 +1452,9 @@ int dev_manager_raid_status(struct dev_manager *dm,
|
||||
|
||||
/* FIXME Check there's only one target */
|
||||
|
||||
if (!dm_get_status_raid(dm->mem, params, &sr))
|
||||
if (!dm_get_status_raid(dm->mem, params, status))
|
||||
goto_out;
|
||||
|
||||
(*status)->mem = dm->mem; /* User has to destroy this mem pool later */
|
||||
(*status)->raid = sr;
|
||||
(*status)->in_sync = dm_make_percent(sr->insync_regions, sr->total_regions);
|
||||
|
||||
r = 1;
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
@@ -1592,7 +1543,7 @@ out:
|
||||
|
||||
int dev_manager_cache_status(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
struct lv_status_cache **status, int *exists)
|
||||
struct lv_status_cache **status)
|
||||
{
|
||||
int r = 0;
|
||||
const char *dlid;
|
||||
@@ -1603,18 +1554,17 @@ int dev_manager_cache_status(struct dev_manager *dm,
|
||||
char *params = NULL;
|
||||
struct dm_status_cache *c;
|
||||
|
||||
*exists = -1;
|
||||
if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
|
||||
return_0;
|
||||
|
||||
if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_cache))))
|
||||
return_0;
|
||||
|
||||
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, 0, 0)))
|
||||
return_0;
|
||||
|
||||
if (!(*exists = info.exists))
|
||||
goto out;
|
||||
|
||||
log_debug_activation("Checking status for cache volume %s.",
|
||||
display_lvname(lv));
|
||||
if (!info.exists)
|
||||
goto_out;
|
||||
|
||||
dm_get_next_target(dmt, NULL, &start, &length, &type, ¶ms);
|
||||
|
||||
@@ -1632,11 +1582,8 @@ int dev_manager_cache_status(struct dev_manager *dm,
|
||||
if (!dm_get_status_cache(dm->mem, params, &c))
|
||||
goto_out;
|
||||
|
||||
if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_cache))))
|
||||
goto_out;
|
||||
|
||||
(*status)->mem = dm->mem; /* User has to destroy this mem pool later */
|
||||
(*status)->cache = c;
|
||||
(*status)->mem = dm->mem; /* User has to destroy this mem pool later */
|
||||
if (c->fail || c->error) {
|
||||
(*status)->data_usage =
|
||||
(*status)->metadata_usage =
|
||||
@@ -1658,10 +1605,10 @@ out:
|
||||
}
|
||||
|
||||
int dev_manager_thin_pool_status(struct dev_manager *dm,
|
||||
const struct logical_volume *lv, int flush,
|
||||
struct lv_status_thin_pool **status, int *exists)
|
||||
const struct logical_volume *lv,
|
||||
struct dm_status_thin_pool **status,
|
||||
int flush)
|
||||
{
|
||||
struct dm_status_thin_pool *dm_status;
|
||||
const char *dlid;
|
||||
struct dm_task *dmt;
|
||||
struct dm_info info;
|
||||
@@ -1670,10 +1617,6 @@ int dev_manager_thin_pool_status(struct dev_manager *dm,
|
||||
char *params = NULL;
|
||||
int r = 0;
|
||||
|
||||
*exists = -1;
|
||||
if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_thin_pool))))
|
||||
return_0;
|
||||
|
||||
/* Build dlid for the thin pool layer */
|
||||
if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
|
||||
return_0;
|
||||
@@ -1681,36 +1624,16 @@ int dev_manager_thin_pool_status(struct dev_manager *dm,
|
||||
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, flush, 0)))
|
||||
return_0;
|
||||
|
||||
if (!(*exists = info.exists))
|
||||
goto out;
|
||||
|
||||
log_debug_activation("Checking thin pool status for LV %s.",
|
||||
display_lvname(lv));
|
||||
if (!info.exists)
|
||||
goto_out;
|
||||
|
||||
dm_get_next_target(dmt, NULL, &start, &length, &type, ¶ms);
|
||||
|
||||
if (!type || strcmp(type, TARGET_NAME_THIN_POOL)) {
|
||||
log_error("Expected %s segment type but got %s instead.",
|
||||
TARGET_NAME_THIN_POOL, type ? type : "NULL");
|
||||
goto out;
|
||||
}
|
||||
/* FIXME Check for thin and check there's exactly one target */
|
||||
|
||||
if (!dm_get_status_thin_pool(dm->mem, params, &dm_status))
|
||||
if (!dm_get_status_thin_pool(dm->mem, params, status))
|
||||
goto_out;
|
||||
|
||||
(*status)->mem = dm->mem;
|
||||
(*status)->thin_pool = dm_status;
|
||||
|
||||
if (dm_status->fail || dm_status->error) {
|
||||
(*status)->data_usage =
|
||||
(*status)->metadata_usage = DM_PERCENT_INVALID;
|
||||
} else {
|
||||
(*status)->data_usage = dm_make_percent(dm_status->used_data_blocks,
|
||||
dm_status->total_data_blocks);
|
||||
(*status)->metadata_usage = dm_make_percent(dm_status->used_metadata_blocks,
|
||||
dm_status->total_metadata_blocks);
|
||||
}
|
||||
|
||||
r = 1;
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
@@ -1718,72 +1641,52 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
int dev_manager_thin_status(struct dev_manager *dm,
|
||||
const struct logical_volume *lv, int flush,
|
||||
struct lv_status_thin **status, int *exists)
|
||||
int dev_manager_thin_pool_percent(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
int metadata, dm_percent_t *percent)
|
||||
{
|
||||
struct dm_status_thin *dm_status;
|
||||
char *name;
|
||||
const char *dlid;
|
||||
struct dm_task *dmt;
|
||||
struct dm_info info;
|
||||
uint64_t start, length;
|
||||
char *type = NULL;
|
||||
char *params = NULL;
|
||||
uint64_t csize;
|
||||
int r = 0;
|
||||
const char *layer = lv_layer(lv);
|
||||
|
||||
*exists = -1;
|
||||
if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_thin))))
|
||||
/* Build a name for the top layer */
|
||||
if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
|
||||
return_0;
|
||||
|
||||
if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
|
||||
if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
|
||||
return_0;
|
||||
|
||||
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, flush, 0)))
|
||||
log_debug_activation("Getting device status percentage for %s.", name);
|
||||
|
||||
if (!(_percent(dm, name, dlid, TARGET_NAME_THIN_POOL, 0,
|
||||
(metadata) ? lv : NULL, percent, NULL, 1)))
|
||||
return_0;
|
||||
|
||||
if (!(*exists = info.exists))
|
||||
goto out;
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_debug_activation("Checking thin status for LV %s.",
|
||||
display_lvname(lv));
|
||||
int dev_manager_thin_percent(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
int mapped, dm_percent_t *percent)
|
||||
{
|
||||
char *name;
|
||||
const char *dlid;
|
||||
const char *layer = lv_layer(lv);
|
||||
|
||||
dm_get_next_target(dmt, NULL, &start, &length, &type, ¶ms);
|
||||
/* Build a name for the top layer */
|
||||
if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
|
||||
return_0;
|
||||
|
||||
if (!type || strcmp(type, TARGET_NAME_THIN)) {
|
||||
log_error("Expected %s segment type but got %s instead.",
|
||||
TARGET_NAME_THIN, type ? type : "NULL");
|
||||
goto out;
|
||||
}
|
||||
if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
|
||||
return_0;
|
||||
|
||||
if (!dm_get_status_thin(dm->mem, params, &dm_status))
|
||||
goto_out;
|
||||
log_debug_activation("Getting device status percentage for %s", name);
|
||||
|
||||
(*status)->mem = dm->mem;
|
||||
(*status)->thin = dm_status;
|
||||
if (!(_percent(dm, name, dlid, TARGET_NAME_THIN, 0,
|
||||
(mapped) ? NULL : lv, percent, NULL, 1)))
|
||||
return_0;
|
||||
|
||||
if (dm_status->fail)
|
||||
(*status)->usage = DM_PERCENT_INVALID;
|
||||
else {
|
||||
/* Pool allocates whole chunk so round-up to nearest one */
|
||||
csize = first_seg(first_seg(lv)->pool_lv)->chunk_size;
|
||||
csize = ((lv->size + csize - 1) / csize) * csize;
|
||||
if (dm_status->mapped_sectors > csize) {
|
||||
log_warn("WARNING: LV %s maps %s while the size is only %s.",
|
||||
display_lvname(lv),
|
||||
display_size(dm->cmd, dm_status->mapped_sectors),
|
||||
display_size(dm->cmd, csize));
|
||||
/* Don't show nonsense numbers like i.e. 1000% full */
|
||||
dm_status->mapped_sectors = csize;
|
||||
}
|
||||
(*status)->usage = dm_make_percent(dm_status->mapped_sectors, csize);
|
||||
}
|
||||
|
||||
r = 1;
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
return r;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1791,7 +1694,7 @@ out:
|
||||
*/
|
||||
int dev_manager_thin_device_id(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
uint32_t *device_id, int *exists)
|
||||
uint32_t *device_id)
|
||||
{
|
||||
const char *dlid;
|
||||
struct dm_task *dmt;
|
||||
@@ -1801,7 +1704,6 @@ int dev_manager_thin_device_id(struct dev_manager *dm,
|
||||
const char *layer = lv_layer(lv);
|
||||
int r = 0;
|
||||
|
||||
*exists = -1;
|
||||
if (lv_is_merging_origin(lv) && !lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
|
||||
/* If the merge has already happened, that table
|
||||
* can already be using correct LV without -real layer */
|
||||
@@ -1814,11 +1716,8 @@ int dev_manager_thin_device_id(struct dev_manager *dm,
|
||||
if (!(dmt = _setup_task_run(DM_DEVICE_TABLE, &info, NULL, dlid, 0, 0, 0, 0, 1, 0)))
|
||||
return_0;
|
||||
|
||||
if (!(*exists = info.exists))
|
||||
goto out;
|
||||
|
||||
log_debug_activation("Checking device id for LV %s.",
|
||||
display_lvname(lv));
|
||||
if (!info.exists)
|
||||
goto_out;
|
||||
|
||||
if (dm_get_next_target(dmt, NULL, &start, &length,
|
||||
&target_type, ¶ms)) {
|
||||
@@ -1847,9 +1746,11 @@ out:
|
||||
}
|
||||
|
||||
int dev_manager_vdo_pool_status(struct dev_manager *dm,
|
||||
const struct logical_volume *lv, int flush,
|
||||
struct lv_status_vdo **status, int *exists)
|
||||
const struct logical_volume *lv,
|
||||
struct lv_status_vdo **vdo_status,
|
||||
int flush)
|
||||
{
|
||||
struct lv_status_vdo *status;
|
||||
const char *dlid;
|
||||
struct dm_info info;
|
||||
uint64_t start, length;
|
||||
@@ -1858,9 +1759,12 @@ int dev_manager_vdo_pool_status(struct dev_manager *dm,
|
||||
char *params = NULL;
|
||||
int r = 0;
|
||||
|
||||
*exists = -1;
|
||||
if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_vdo))))
|
||||
return_0;
|
||||
*vdo_status = NULL;
|
||||
|
||||
if (!(status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_vdo)))) {
|
||||
log_error("Cannot allocate VDO status structure.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
|
||||
return_0;
|
||||
@@ -1868,11 +1772,8 @@ int dev_manager_vdo_pool_status(struct dev_manager *dm,
|
||||
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, flush, 0)))
|
||||
return_0;
|
||||
|
||||
if (!(*exists = info.exists))
|
||||
goto out;
|
||||
|
||||
log_debug_activation("Checking VDO pool status for LV %s.",
|
||||
display_lvname(lv));
|
||||
if (!info.exists)
|
||||
goto_out;
|
||||
|
||||
if (dm_get_next_target(dmt, NULL, &start, &length, &type, ¶ms)) {
|
||||
log_error("More then one table line found for %s.",
|
||||
@@ -1886,10 +1787,11 @@ int dev_manager_vdo_pool_status(struct dev_manager *dm,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!parse_vdo_pool_status(dm->mem, lv, params, *status))
|
||||
if (!parse_vdo_pool_status(dm->mem, lv, params, status))
|
||||
goto_out;
|
||||
|
||||
(*status)->mem = dm->mem;
|
||||
status->mem = dm->mem;
|
||||
*vdo_status = status;
|
||||
|
||||
r = 1;
|
||||
out:
|
||||
@@ -2325,31 +2227,21 @@ static int _pool_callback(struct dm_tree_node *node,
|
||||
const struct pool_cb_data *data = cb_data;
|
||||
const struct logical_volume *pool_lv = data->pool_lv;
|
||||
const struct logical_volume *mlv = first_seg(pool_lv)->metadata_lv;
|
||||
struct cmd_context *cmd = pool_lv->vg->cmd;
|
||||
long buf[64 / sizeof(long)]; /* buffer for short disk header (64B) */
|
||||
int args = 0;
|
||||
char *mpath;
|
||||
const char *argv[19] = { /* Max supported 15 args */
|
||||
find_config_tree_str_allow_empty(cmd, data->exec, NULL)
|
||||
find_config_tree_str_allow_empty(pool_lv->vg->cmd, data->exec, NULL)
|
||||
};
|
||||
|
||||
if (!*argv[0]) /* *_check tool is unconfigured/disabled with "" setting */
|
||||
return 1;
|
||||
|
||||
if (lv_is_cache_vol(pool_lv)) {
|
||||
if (!(mpath = lv_dmpath_suffix_dup(data->dm->mem, pool_lv, "-cmeta"))) {
|
||||
log_error("Failed to build device path for checking cachevol metadata %s.",
|
||||
display_lvname(pool_lv));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (!(mpath = lv_dmpath_dup(data->dm->mem, mlv))) {
|
||||
log_error("Failed to build device path for checking pool metadata %s.",
|
||||
display_lvname(mlv));
|
||||
return 0;
|
||||
}
|
||||
if (!(mpath = lv_dmpath_dup(data->dm->mem, mlv))) {
|
||||
log_error("Failed to build device path for checking pool metadata %s.",
|
||||
display_lvname(mlv));
|
||||
return 0;
|
||||
}
|
||||
log_debug("Running check command on %s", mpath);
|
||||
|
||||
if (data->skip_zero) {
|
||||
if ((fd = open(mpath, O_RDONLY)) < 0) {
|
||||
@@ -2377,7 +2269,7 @@ static int _pool_callback(struct dm_tree_node *node,
|
||||
}
|
||||
}
|
||||
|
||||
if (!(cn = find_config_tree_array(cmd, data->opts, NULL))) {
|
||||
if (!(cn = find_config_tree_array(mlv->vg->cmd, data->opts, NULL))) {
|
||||
log_error(INTERNAL_ERROR "Unable to find configuration for pool check options.");
|
||||
return 0;
|
||||
}
|
||||
@@ -2399,7 +2291,7 @@ static int _pool_callback(struct dm_tree_node *node,
|
||||
|
||||
argv[++args] = mpath;
|
||||
|
||||
if (!(ret = exec_cmd(cmd, (const char * const *)argv,
|
||||
if (!(ret = exec_cmd(pool_lv->vg->cmd, (const char * const *)argv,
|
||||
&status, 0))) {
|
||||
if (status == ENOENT) {
|
||||
log_warn("WARNING: Check is skipped, please install recommended missing binary %s!",
|
||||
@@ -2408,7 +2300,7 @@ static int _pool_callback(struct dm_tree_node *node,
|
||||
}
|
||||
|
||||
if ((data->version.maj || data->version.min || data->version.patch) &&
|
||||
!_check_tool_version(cmd, argv[0],
|
||||
!_check_tool_version(pool_lv->vg->cmd, argv[0],
|
||||
data->version.maj, data->version.min, data->version.patch)) {
|
||||
log_warn("WARNING: Check is skipped, please upgrade installed version of %s!",
|
||||
argv[0]);
|
||||
@@ -2452,6 +2344,10 @@ static int _pool_register_callback(struct dev_manager *dm,
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
/* Skip for single-device cache pool */
|
||||
if (lv_is_cache(lv) && lv_is_cache_vol(first_seg(lv)->pool_lv))
|
||||
return 1;
|
||||
|
||||
if (!(data = dm_pool_zalloc(dm->mem, sizeof(*data)))) {
|
||||
log_error("Failed to allocated path for callback.");
|
||||
return 0;
|
||||
@@ -2724,10 +2620,6 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
if (!_add_lv_to_dtree(dm, dtree, seg->writecache, dm->activation ? origin_only : 1))
|
||||
return_0;
|
||||
}
|
||||
if (seg->integrity_meta_dev && seg_is_integrity(seg)) {
|
||||
if (!_add_lv_to_dtree(dm, dtree, seg->integrity_meta_dev, dm->activation ? origin_only : 1))
|
||||
return_0;
|
||||
}
|
||||
if (seg->pool_lv &&
|
||||
(lv_is_cache_pool(seg->pool_lv) || lv_is_cache_vol(seg->pool_lv) || dm->track_external_lv_deps) &&
|
||||
/* When activating and not origin_only detect linear 'overlay' over pool */
|
||||
@@ -3184,11 +3076,6 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
|
||||
lv_layer(seg->writecache)))
|
||||
return_0;
|
||||
|
||||
if (seg->integrity_meta_dev && !laopts->origin_only &&
|
||||
!_add_new_lv_to_dtree(dm, dtree, seg->integrity_meta_dev, laopts,
|
||||
lv_layer(seg->integrity_meta_dev)))
|
||||
return_0;
|
||||
|
||||
/* Add any LVs used by this segment */
|
||||
for (s = 0; s < seg->area_count; ++s) {
|
||||
if ((seg_type(seg, s) == AREA_LV) &&
|
||||
@@ -3274,8 +3161,8 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
char *dlid_meta;
|
||||
char *dlid_data;
|
||||
char *dlid_pool;
|
||||
uint64_t meta_size = first_seg(lv)->metadata_len;
|
||||
uint64_t data_size = first_seg(lv)->data_len;
|
||||
uint64_t meta_len = first_seg(lv)->metadata_len;
|
||||
uint64_t data_len = first_seg(lv)->data_len;
|
||||
uint16_t udev_flags = _get_udev_flags(dm, lv, layer,
|
||||
laopts->noscan, laopts->temporary,
|
||||
0);
|
||||
@@ -3323,12 +3210,12 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
|
||||
if (dm->track_pending_delete) {
|
||||
log_debug_activation("Using error for pending meta delete %s.", display_lvname(lv));
|
||||
if (!dm_tree_node_add_error_target(dnode_meta, meta_size))
|
||||
if (!dm_tree_node_add_error_target(dnode_meta, (uint64_t)lv->vg->extent_size * meta_len))
|
||||
return_0;
|
||||
} else {
|
||||
/* add load_segment to meta dnode: linear, size of meta area */
|
||||
if (!add_linear_area_to_dtree(dnode_meta,
|
||||
meta_size,
|
||||
meta_len,
|
||||
lv->vg->extent_size,
|
||||
lv->vg->cmd->use_linear_target,
|
||||
lv->vg->name, lv->name))
|
||||
@@ -3352,19 +3239,19 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
|
||||
if (dm->track_pending_delete) {
|
||||
log_debug_activation("Using error for pending data delete %s.", display_lvname(lv));
|
||||
if (!dm_tree_node_add_error_target(dnode_data, data_size))
|
||||
if (!dm_tree_node_add_error_target(dnode_data, (uint64_t)lv->vg->extent_size * data_len))
|
||||
return_0;
|
||||
} else {
|
||||
/* add load_segment to data dnode: linear, size of data area */
|
||||
if (!add_linear_area_to_dtree(dnode_data,
|
||||
data_size,
|
||||
data_len,
|
||||
lv->vg->extent_size,
|
||||
lv->vg->cmd->use_linear_target,
|
||||
lv->vg->name, lv->name))
|
||||
return_0;
|
||||
|
||||
/* add seg_area to prev load_seg: offset 0 maps to cachepool lv after meta */
|
||||
if (!dm_tree_node_add_target_area(dnode_data, NULL, dlid_pool, meta_size))
|
||||
if (!dm_tree_node_add_target_area(dnode_data, NULL, dlid_pool, meta_len))
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
@@ -3429,10 +3316,6 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
if (!layer && lv_is_new_thin_pool(lv))
|
||||
layer = lv_layer(lv);
|
||||
|
||||
/* Adds -real to the dm uuid of wcorig LV. */
|
||||
if (!layer && lv_is_writecache_origin(lv))
|
||||
layer = lv_layer(lv); /* "real" */
|
||||
|
||||
if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
|
||||
return_0;
|
||||
|
||||
@@ -3544,12 +3427,6 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
!_pool_register_callback(dm, dnode, lv))
|
||||
return_0;
|
||||
|
||||
if (lv_is_cache(lv) && lv_is_cache_vol(first_seg(lv)->pool_lv) &&
|
||||
/* Register callback only for layer activation or non-layered cache LV */
|
||||
(layer || !lv_layer(lv)) &&
|
||||
!_pool_register_callback(dm, dnode, lv))
|
||||
return_0;
|
||||
|
||||
/*
|
||||
* Update tables for ANY PVMOVE holders for active LV where the name starts with 'pvmove',
|
||||
* but it's not anymore PVMOVE LV and also it's not a PVMOVE _mimage LV.
|
||||
|
@@ -59,7 +59,7 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
|
||||
dm_percent_t *percent, uint32_t *event_nr);
|
||||
int dev_manager_raid_status(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
struct lv_status_raid **status, int *exists);
|
||||
struct dm_status_raid **status);
|
||||
int dev_manager_raid_message(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
const char *msg);
|
||||
@@ -68,19 +68,24 @@ int dev_manager_writecache_message(struct dev_manager *dm,
|
||||
const char *msg);
|
||||
int dev_manager_cache_status(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
struct lv_status_cache **status, int *exists);
|
||||
int dev_manager_thin_status(struct dev_manager *dm,
|
||||
const struct logical_volume *lv, int flush,
|
||||
struct lv_status_thin **status, int *exists);
|
||||
struct lv_status_cache **status);
|
||||
int dev_manager_thin_pool_status(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
struct dm_status_thin_pool **status,
|
||||
int flush);
|
||||
int dev_manager_thin_pool_percent(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
int metadata, dm_percent_t *percent);
|
||||
int dev_manager_thin_percent(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
int mapped, dm_percent_t *percent);
|
||||
int dev_manager_thin_device_id(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
uint32_t *device_id, int *exist);
|
||||
int dev_manager_thin_pool_status(struct dev_manager *dm,
|
||||
const struct logical_volume *lv, int flush,
|
||||
struct lv_status_thin_pool **status, int *exists);
|
||||
uint32_t *device_id);
|
||||
int dev_manager_vdo_pool_status(struct dev_manager *dm,
|
||||
const struct logical_volume *lv, int flush,
|
||||
struct lv_status_vdo **status, int *exists);
|
||||
const struct logical_volume *lv,
|
||||
struct lv_status_vdo **vdo_status,
|
||||
int flush);
|
||||
int dev_manager_suspend(struct dev_manager *dm, const struct logical_volume *lv,
|
||||
struct lv_activate_opts *laopts, int lockfs, int flush_required);
|
||||
int dev_manager_activate(struct dev_manager *dm, const struct logical_volume *lv,
|
||||
|
@@ -76,7 +76,7 @@ static int _rm_dir(const char *dev_dir, const char *vg_name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dir_exists(vg_path) && dm_is_empty_dir(vg_path)) {
|
||||
if (dir_exists(vg_path) && is_empty_dir(vg_path)) {
|
||||
log_very_verbose("Removing directory %s", vg_path);
|
||||
rmdir(vg_path);
|
||||
}
|
||||
@@ -93,7 +93,7 @@ static void _rm_blks(const char *dir)
|
||||
DIR *d;
|
||||
|
||||
if (!(d = opendir(dir))) {
|
||||
log_sys_debug("opendir", dir);
|
||||
log_sys_error("opendir", dir);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ static void _rm_blks(const char *dir)
|
||||
continue;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s", dir, name) == -1) {
|
||||
log_debug("Couldn't create path for %s.", name);
|
||||
log_error("Couldn't create path for %s", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -113,12 +113,12 @@ static void _rm_blks(const char *dir)
|
||||
continue;
|
||||
log_very_verbose("Removing %s", path);
|
||||
if (unlink(path) < 0)
|
||||
log_sys_debug("unlink", path);
|
||||
log_sys_error("unlink", path);
|
||||
}
|
||||
}
|
||||
|
||||
if (closedir(d))
|
||||
log_sys_debug("closedir", dir);
|
||||
log_sys_error("closedir", dir);
|
||||
}
|
||||
|
||||
static int _mk_link(const char *dev_dir, const char *vg_name,
|
||||
@@ -169,7 +169,7 @@ static int _mk_link(const char *dev_dir, const char *vg_name,
|
||||
|
||||
log_very_verbose("Removing %s", lvm1_group_path);
|
||||
if (unlink(lvm1_group_path) < 0)
|
||||
log_sys_debug("unlink", lvm1_group_path);
|
||||
log_sys_error("unlink", lvm1_group_path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ struct fs_op_parms {
|
||||
char *lv_name;
|
||||
char *dev;
|
||||
char *old_lv_name;
|
||||
char names[];
|
||||
char names[0];
|
||||
};
|
||||
|
||||
static void _store_str(char **pos, char **ptr, const char *str)
|
||||
|
956
lib/cache/lvmcache.c
vendored
956
lib/cache/lvmcache.c
vendored
File diff suppressed because it is too large
Load Diff
26
lib/cache/lvmcache.h
vendored
26
lib/cache/lvmcache.h
vendored
@@ -69,19 +69,18 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset);
|
||||
int lvmcache_label_scan(struct cmd_context *cmd);
|
||||
int lvmcache_label_rescan_vg(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
||||
int lvmcache_label_rescan_vg_rw(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
||||
int lvmcache_label_reopen_vg_rw(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
||||
|
||||
/* Add/delete a device */
|
||||
struct lvmcache_info *lvmcache_add(struct cmd_context *cmd, struct labeller *labeller, const char *pvid,
|
||||
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
struct device *dev, uint64_t label_sector,
|
||||
const char *vgname, const char *vgid,
|
||||
uint32_t vgstatus, int *is_duplicate);
|
||||
int lvmcache_add_orphan_vginfo(struct cmd_context *cmd, const char *vgname, struct format_type *fmt);
|
||||
int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt);
|
||||
void lvmcache_del(struct lvmcache_info *info);
|
||||
void lvmcache_del_dev(struct device *dev);
|
||||
|
||||
/* Update things */
|
||||
int lvmcache_update_vgname_and_id(struct cmd_context *cmd, struct lvmcache_info *info,
|
||||
int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
|
||||
struct lvmcache_vgsummary *vgsummary);
|
||||
int lvmcache_update_vg_from_read(struct volume_group *vg, unsigned precommitted);
|
||||
int lvmcache_update_vg_from_write(struct volume_group *vg);
|
||||
@@ -162,6 +161,11 @@ struct device *lvmcache_device(struct lvmcache_info *info);
|
||||
unsigned lvmcache_mda_count(struct lvmcache_info *info);
|
||||
uint64_t lvmcache_smallest_mda_size(struct lvmcache_info *info);
|
||||
|
||||
struct metadata_area *lvmcache_get_mda(struct cmd_context *cmd,
|
||||
const char *vgname,
|
||||
struct device *dev,
|
||||
int use_mda_num);
|
||||
|
||||
bool lvmcache_has_duplicate_devs(void);
|
||||
void lvmcache_del_dev_from_duplicates(struct device *dev);
|
||||
bool lvmcache_dev_is_unused_duplicate(struct device *dev);
|
||||
@@ -170,7 +174,6 @@ int lvmcache_get_unused_duplicates(struct cmd_context *cmd, struct dm_list *head
|
||||
int vg_has_duplicate_pvs(struct volume_group *vg);
|
||||
|
||||
int lvmcache_found_duplicate_vgnames(void);
|
||||
bool lvmcache_has_duplicate_local_vgname(const char *vgid, const char *vgname);
|
||||
|
||||
int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd);
|
||||
|
||||
@@ -213,17 +216,4 @@ void lvmcache_get_bad_mdas(struct cmd_context *cmd,
|
||||
const char *vgname, const char *vgid,
|
||||
struct dm_list *bad_mda_list);
|
||||
|
||||
void lvmcache_get_mdas(struct cmd_context *cmd,
|
||||
const char *vgname, const char *vgid,
|
||||
struct dm_list *mda_list);
|
||||
|
||||
const char *dev_filtered_reason(struct device *dev);
|
||||
const char *devname_error_reason(const char *devname);
|
||||
|
||||
struct metadata_area *lvmcache_get_dev_mda(struct device *dev, int mda_num);
|
||||
|
||||
void lvmcache_extra_md_component_checks(struct cmd_context *cmd);
|
||||
|
||||
unsigned int lvmcache_vg_info_count(void);
|
||||
|
||||
#endif
|
||||
|
@@ -32,7 +32,6 @@
|
||||
#include "lib/cache/lvmcache.h"
|
||||
#include "lib/format_text/archiver.h"
|
||||
#include "lib/lvmpolld/lvmpolld-client.h"
|
||||
#include "lib/device/device_id.h"
|
||||
|
||||
#include <locale.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -230,7 +229,7 @@ static void _get_sysfs_dir(struct cmd_context *cmd, char *buf, size_t buf_size)
|
||||
return;
|
||||
}
|
||||
|
||||
(void) dm_strncpy(buf, sys_mnt, buf_size);
|
||||
strncpy(buf, sys_mnt, buf_size);
|
||||
}
|
||||
|
||||
static uint32_t _parse_debug_fields(struct cmd_context *cmd, int cfg, const char *cfgname)
|
||||
@@ -661,8 +660,6 @@ static int _process_config(struct cmd_context *cmd)
|
||||
*/
|
||||
cmd->default_settings.udev_fallback = udev_disabled ? 1 : -1;
|
||||
|
||||
cmd->default_settings.issue_discards = find_config_tree_bool(cmd, devices_issue_discards_CFG, NULL);
|
||||
|
||||
init_retry_deactivation(find_config_tree_bool(cmd, activation_retry_deactivation_CFG, NULL));
|
||||
|
||||
init_activation_checks(find_config_tree_bool(cmd, activation_checks_CFG, NULL));
|
||||
@@ -1069,7 +1066,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)
|
||||
{
|
||||
@@ -1088,9 +1085,6 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
|
||||
* sysfs filter. Only available on 2.6 kernels. Non-critical.
|
||||
* Listed first because it's very efficient at eliminating
|
||||
* unavailable devices.
|
||||
*
|
||||
* TODO: I suspect that using the lvm_type and device_id
|
||||
* filters before this one may be more efficient.
|
||||
*/
|
||||
if (find_config_tree_bool(cmd, devices_sysfs_scan_CFG, NULL)) {
|
||||
if ((filters[nr_filt] = sysfs_filter_create()))
|
||||
@@ -1129,13 +1123,6 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
|
||||
}
|
||||
nr_filt++;
|
||||
|
||||
/* filter based on the device_ids saved in the devices file */
|
||||
if (!(filters[nr_filt] = deviceid_filter_create(cmd))) {
|
||||
log_error("Failed to create deviceid device filter");
|
||||
goto bad;
|
||||
}
|
||||
nr_filt++;
|
||||
|
||||
/* usable device filter. Required. */
|
||||
if (!(filters[nr_filt] = usable_filter_create(cmd, cmd->dev_types, FILTER_MODE_NO_LVMETAD))) {
|
||||
log_error("Failed to create usabled device filter");
|
||||
@@ -1289,7 +1276,7 @@ int init_lvmcache_orphans(struct cmd_context *cmd)
|
||||
struct format_type *fmt;
|
||||
|
||||
dm_list_iterate_items(fmt, &cmd->formats)
|
||||
if (!lvmcache_add_orphan_vginfo(cmd, fmt->orphan_vg_name, fmt))
|
||||
if (!lvmcache_add_orphan_vginfo(fmt->orphan_vg_name, fmt))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
@@ -1375,11 +1362,6 @@ static int _init_segtypes(struct cmd_context *cmd)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#ifdef INTEGRITY_INTERNAL
|
||||
if (!init_integrity_segtypes(cmd, &seglib))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1498,7 +1480,6 @@ int init_run_by_dmeventd(struct cmd_context *cmd)
|
||||
init_dmeventd_monitor(DMEVENTD_MONITOR_IGNORE);
|
||||
init_ignore_suspended_devices(1);
|
||||
init_disable_dmeventd_monitoring(1); /* Lock settings */
|
||||
cmd->run_by_dmeventd = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1612,7 +1593,6 @@ struct cmd_context *create_toolcontext(unsigned is_clvmd,
|
||||
dm_list_init(&cmd->formats);
|
||||
dm_list_init(&cmd->segtypes);
|
||||
dm_list_init(&cmd->tags);
|
||||
dm_list_init(&cmd->hints);
|
||||
dm_list_init(&cmd->config_files);
|
||||
label_init();
|
||||
|
||||
@@ -1731,8 +1711,6 @@ struct cmd_context *create_toolcontext(unsigned is_clvmd,
|
||||
if (!_init_dev_cache(cmd))
|
||||
goto_out;
|
||||
|
||||
devices_file_init(cmd);
|
||||
|
||||
memlock_init(cmd);
|
||||
|
||||
if (!_init_formats(cmd))
|
||||
@@ -1858,7 +1836,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);
|
||||
@@ -1938,8 +1915,6 @@ int refresh_toolcontext(struct cmd_context *cmd)
|
||||
if (!_init_dev_cache(cmd))
|
||||
return_0;
|
||||
|
||||
devices_file_init(cmd);
|
||||
|
||||
if (!_init_formats(cmd))
|
||||
return_0;
|
||||
|
||||
@@ -1989,7 +1964,6 @@ void destroy_toolcontext(struct cmd_context *cmd)
|
||||
_destroy_filters(cmd);
|
||||
if (cmd->mem)
|
||||
dm_pool_destroy(cmd->mem);
|
||||
devices_file_exit(cmd);
|
||||
dev_cache_exit();
|
||||
_destroy_dev_types(cmd);
|
||||
_destroy_tags(cmd);
|
||||
|
@@ -39,7 +39,7 @@ struct config_info {
|
||||
int udev_rules;
|
||||
int udev_sync;
|
||||
int udev_fallback;
|
||||
int issue_discards;
|
||||
int cache_vgmetadata;
|
||||
const char *msg_prefix;
|
||||
const char *fmt_name;
|
||||
const char *dmeventd_executable;
|
||||
@@ -182,27 +182,13 @@ struct cmd_context {
|
||||
unsigned pvscan_recreate_hints:1; /* enable special case hint handling for pvscan --cache */
|
||||
unsigned scan_lvs:1;
|
||||
unsigned wipe_outdated_pvs:1;
|
||||
unsigned enable_devices_list:1; /* command is using --devices option */
|
||||
unsigned enable_devices_file:1; /* command is using devices file */
|
||||
unsigned pending_devices_file:1; /* command may create and enable devices file */
|
||||
unsigned create_edit_devices_file:1; /* command expects to create and/or edit devices file */
|
||||
unsigned edit_devices_file:1; /* command expects to edit devices file */
|
||||
unsigned filter_deviceid_skip:1; /* don't use filter-deviceid */
|
||||
unsigned filter_regex_with_devices_file:1; /* use filter-regex even when devices file is enabled */
|
||||
unsigned filter_nodata_only:1; /* only use filters that do not require data from the dev */
|
||||
unsigned run_by_dmeventd:1; /* command is being run by dmeventd */
|
||||
unsigned sysinit:1; /* --sysinit is used */
|
||||
|
||||
/*
|
||||
* Devices and filtering.
|
||||
*/
|
||||
struct dev_filter *filter;
|
||||
struct dm_list hints;
|
||||
struct dm_list use_devices; /* struct dev_use for each entry in devices file */
|
||||
const char *md_component_checks;
|
||||
const char *search_for_devnames; /* config file setting */
|
||||
const char *devicesfile; /* from --devicesfile option */
|
||||
struct dm_list deviceslist; /* from --devices option, struct dm_str_list */
|
||||
|
||||
/*
|
||||
* Configuration.
|
||||
@@ -234,7 +220,6 @@ struct cmd_context {
|
||||
char system_dir[PATH_MAX];
|
||||
char dev_dir[PATH_MAX];
|
||||
char proc_dir[PATH_MAX];
|
||||
char devices_file_path[PATH_MAX];
|
||||
|
||||
/*
|
||||
* Reporting.
|
||||
|
@@ -503,10 +503,10 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
||||
{
|
||||
char *fb, *fe;
|
||||
int r = 0;
|
||||
int sz, use_plain_read = 1;
|
||||
int use_mmap = 1;
|
||||
off_t mmap_offset = 0;
|
||||
char *buf = NULL;
|
||||
struct config_source *cs = dm_config_get_custom(cft);
|
||||
size_t rsize;
|
||||
|
||||
if (!_is_file_based_config_source(cs->type)) {
|
||||
log_error(INTERNAL_ERROR "config_file_read_fd: expected file, special file "
|
||||
@@ -515,28 +515,26 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only use plain read with regular files */
|
||||
/* Only use mmap with regular files */
|
||||
if (!(dev->flags & DEV_REGULAR) || size2)
|
||||
use_plain_read = 0;
|
||||
use_mmap = 0;
|
||||
|
||||
if (!(buf = malloc(size + size2))) {
|
||||
log_error("Failed to allocate circular buffer.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (use_plain_read) {
|
||||
/* Note: also used for lvm.conf to read all settings */
|
||||
for (rsize = 0; rsize < size; rsize += sz) {
|
||||
do {
|
||||
sz = read(dev_fd(dev), buf + rsize, size - rsize);
|
||||
} while ((sz < 0) && ((errno == EINTR) || (errno == EAGAIN)));
|
||||
|
||||
if (sz < 0) {
|
||||
log_sys_error("read", dev_name(dev));
|
||||
goto out;
|
||||
}
|
||||
if (use_mmap) {
|
||||
mmap_offset = offset % lvm_getpagesize();
|
||||
/* memory map the file */
|
||||
fb = mmap((caddr_t) 0, size + mmap_offset, PROT_READ,
|
||||
MAP_PRIVATE, dev_fd(dev), offset - mmap_offset);
|
||||
if (fb == (caddr_t) (-1)) {
|
||||
log_sys_error("mmap", dev_name(dev));
|
||||
goto out;
|
||||
}
|
||||
fb = fb + mmap_offset;
|
||||
} else {
|
||||
if (!(buf = malloc(size + size2))) {
|
||||
log_error("Failed to allocate circular buffer.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!dev_read_bytes(dev, offset, size, buf))
|
||||
goto out;
|
||||
|
||||
@@ -544,9 +542,9 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
||||
if (!dev_read_bytes(dev, offset2, size2, buf + size))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
fb = buf;
|
||||
fb = buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* The checksum passed in is the checksum from the mda_header
|
||||
@@ -575,7 +573,15 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
free(buf);
|
||||
if (!use_mmap)
|
||||
free(buf);
|
||||
else {
|
||||
/* unmap the file */
|
||||
if (munmap(fb - mmap_offset, size + mmap_offset)) {
|
||||
log_sys_error("munmap", dev_name(dev));
|
||||
r = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -710,7 +716,7 @@ static struct dm_config_value *_get_def_array_values(struct cmd_context *cmd,
|
||||
return array;
|
||||
}
|
||||
|
||||
if (!(token = enc_value = strdup(def_enc_value))) {
|
||||
if (!(p = token = enc_value = strdup(def_enc_value))) {
|
||||
log_error("_get_def_array_values: strdup failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -1141,10 +1147,8 @@ int config_def_check(struct cft_check_handle *handle)
|
||||
* sections and settings with full path as a key.
|
||||
* If section name is variable, use '#' as a substitute.
|
||||
*/
|
||||
*vp = 0;
|
||||
*rp = 0;
|
||||
if (!handle->cmd->cft_def_hash) {
|
||||
if (!(handle->cmd->cft_def_hash = dm_hash_create(60))) {
|
||||
if (!(handle->cmd->cft_def_hash = dm_hash_create(64))) {
|
||||
log_error("Failed to create configuration definition hash.");
|
||||
r = 0; goto out;
|
||||
}
|
||||
@@ -1710,7 +1714,6 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
|
||||
const char *node_type_name = cn->v ? "option" : "section";
|
||||
char path[CFG_PATH_MAX_LEN];
|
||||
char commentline[MAX_COMMENT_LINE+1];
|
||||
int is_deprecated = 0;
|
||||
|
||||
if (cn->id <= 0)
|
||||
return 1;
|
||||
@@ -1724,14 +1727,13 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
|
||||
|
||||
cfg_def = cfg_def_get_item_p(cn->id);
|
||||
|
||||
is_deprecated = _def_node_is_deprecated(cfg_def, out->tree_spec);
|
||||
|
||||
if (out->tree_spec->withsummary || out->tree_spec->withcomments) {
|
||||
_cfg_def_make_path(path, sizeof(path), cfg_def->id, cfg_def, 1);
|
||||
fprintf(out->fp, "\n");
|
||||
fprintf(out->fp, "%s# Configuration %s %s.\n", line, node_type_name, path);
|
||||
|
||||
if (out->tree_spec->withcomments && is_deprecated && cfg_def->deprecation_comment)
|
||||
if (out->tree_spec->withcomments &&
|
||||
_def_node_is_deprecated(cfg_def, out->tree_spec))
|
||||
fprintf(out->fp, "%s# %s", line, cfg_def->deprecation_comment);
|
||||
|
||||
if (cfg_def->comment) {
|
||||
@@ -1742,14 +1744,14 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
|
||||
continue;
|
||||
commentline[0] = '\0';
|
||||
}
|
||||
fprintf(out->fp, "%s#%s%s\n", line, commentline[0] ? " " : "", commentline);
|
||||
fprintf(out->fp, "%s# %s\n", line, commentline);
|
||||
/* withsummary prints only the first comment line. */
|
||||
if (!out->tree_spec->withcomments)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_deprecated)
|
||||
if (_def_node_is_deprecated(cfg_def, out->tree_spec))
|
||||
fprintf(out->fp, "%s# This configuration %s is deprecated.\n", line, node_type_name);
|
||||
|
||||
if (cfg_def->flags & CFG_ADVANCED)
|
||||
@@ -1777,7 +1779,7 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
|
||||
return_0;
|
||||
fprintf(out->fp, "%s# Available since version %s.\n", line, version);
|
||||
|
||||
if (is_deprecated) {
|
||||
if (_def_node_is_deprecated(cfg_def, out->tree_spec)) {
|
||||
if (!_get_config_node_version(cfg_def->deprecated_since_version, version))
|
||||
return_0;
|
||||
fprintf(out->fp, "%s# Deprecated since version %s.\n", line, version);
|
||||
|
@@ -288,32 +288,6 @@ cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, C
|
||||
"preferred_names = [ \"^/dev/mpath/\", \"^/dev/mapper/mpath\", \"^/dev/[hs]d\" ]\n"
|
||||
"#\n")
|
||||
|
||||
cfg(devices_use_devicesfile_CFG, "use_devicesfile", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_USE_DEVICES_FILE, vsn(2, 3, 12), NULL, 0, NULL,
|
||||
"Enable or disable the use of a devices file.\n"
|
||||
"When enabled, lvm will only use devices that\n"
|
||||
"are lised in the devices file. A devices file will\n"
|
||||
"be used, regardless of this setting, when the --devicesfile\n"
|
||||
"option is set to a specific file name.\n")
|
||||
|
||||
cfg(devices_devicesfile_CFG, "devicesfile", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_DEVICES_FILE, vsn(2, 3, 12), NULL, 0, NULL,
|
||||
"The name of the system devices file, listing devices that LVM should use.\n"
|
||||
"This should not be used to select a non-system devices file.\n"
|
||||
"The --devicesfile option is intended for alternative devices files.\n")
|
||||
|
||||
cfg(devices_search_for_devnames_CFG, "search_for_devnames", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_SEARCH_FOR_DEVNAMES, vsn(2, 3, 12), NULL, 0, NULL,
|
||||
"Look outside of the devices file for missing devname entries.\n"
|
||||
"A devname entry is used for a device that does not have a stable\n"
|
||||
"device id, e.g. wwid, so the unstable device name is used as\n"
|
||||
"the device id. After reboot, or if the device is reattached,\n"
|
||||
"the device name may change, in which case lvm will not find\n"
|
||||
"the expected PV on the device listed in the devices file.\n"
|
||||
"This setting controls whether lvm will search other devices,\n"
|
||||
"outside the devices file, to look for the missing PV on a\n"
|
||||
"renamed device. If \"none\", lvm will not look at other devices,\n"
|
||||
"and the PV may appear to be missing. If \"auto\", lvm will look\n"
|
||||
"at other devices, but only those that are likely to have the PV.\n"
|
||||
"If \"all\", lvm will look at all devices on the system.\n")
|
||||
|
||||
cfg_array(devices_filter_CFG, "filter", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, "#Sa|.*|", vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Limit the block devices that are used by LVM commands.\n"
|
||||
"This is a list of regular expressions used to accept or reject block\n"
|
||||
@@ -352,16 +326,16 @@ cfg_array(devices_global_filter_CFG, "global_filter", devices_CFG_SECTION, CFG_D
|
||||
"global_filter are not opened by LVM.\n")
|
||||
|
||||
cfg_runtime(devices_cache_CFG, "cache", devices_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 0, 0), vsn(1, 2, 19), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg_runtime(devices_cache_dir_CFG, "cache_dir", devices_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 2, 19), vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg(devices_cache_file_prefix_CFG, "cache_file_prefix", devices_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_CACHE_FILE_PREFIX, vsn(1, 2, 19), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg(devices_write_cache_state_CFG, "write_cache_state", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg_array(devices_types_CFG, "types", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED | CFG_ADVANCED, CFG_TYPE_INT | CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"List of additional acceptable block device types.\n"
|
||||
@@ -427,15 +401,15 @@ cfg(devices_fw_raid_component_detection_CFG, "fw_raid_component_detection", devi
|
||||
cfg(devices_md_chunk_alignment_CFG, "md_chunk_alignment", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MD_CHUNK_ALIGNMENT, vsn(2, 2, 48), NULL, 0, NULL,
|
||||
"Align the start of a PV data area with md device's stripe-width.\n"
|
||||
"This applies if a PV is placed directly on an md device.\n"
|
||||
"default_data_alignment will be overridden if it is not aligned\n"
|
||||
"default_data_alignment will be overriden if it is not aligned\n"
|
||||
"with the value detected for this setting.\n"
|
||||
"This setting is overridden by data_alignment_detection,\n"
|
||||
"This setting is overriden by data_alignment_detection,\n"
|
||||
"data_alignment, and the --dataalignment option.\n")
|
||||
|
||||
cfg(devices_default_data_alignment_CFG, "default_data_alignment", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, FIRST_PE_AT_ONE_MB_IN_MB, vsn(2, 2, 75), NULL, 0, NULL,
|
||||
"Align the start of a PV data area with this number of MiB.\n"
|
||||
"Set to 1 for 1MiB, 2 for 2MiB, etc. Set to 0 to disable.\n"
|
||||
"This setting is overridden by data_alignment and the --dataalignment\n"
|
||||
"This setting is overriden by data_alignment and the --dataalignment\n"
|
||||
"option.\n")
|
||||
|
||||
cfg(devices_data_alignment_detection_CFG, "data_alignment_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DATA_ALIGNMENT_DETECTION, vsn(2, 2, 51), NULL, 0, NULL,
|
||||
@@ -447,9 +421,9 @@ cfg(devices_data_alignment_detection_CFG, "data_alignment_detection", devices_CF
|
||||
"preferred unit of receiving I/O, e.g. MD stripe width.\n"
|
||||
"minimum_io_size is used if optimal_io_size is undefined (0).\n"
|
||||
"If md_chunk_alignment is enabled, that detects the optimal_io_size.\n"
|
||||
"default_data_alignment and md_chunk_alignment will be overridden\n"
|
||||
"default_data_alignment and md_chunk_alignment will be overriden\n"
|
||||
"if they are not aligned with the value detected for this setting.\n"
|
||||
"This setting is overridden by data_alignment and the --dataalignment\n"
|
||||
"This setting is overriden by data_alignment and the --dataalignment\n"
|
||||
"option.\n")
|
||||
|
||||
cfg(devices_data_alignment_CFG, "data_alignment", devices_CFG_SECTION, 0, CFG_TYPE_INT, 0, vsn(2, 2, 45), NULL, 0, NULL,
|
||||
@@ -457,7 +431,7 @@ cfg(devices_data_alignment_CFG, "data_alignment", devices_CFG_SECTION, 0, CFG_TY
|
||||
"When non-zero, this setting overrides default_data_alignment.\n"
|
||||
"Set to 0 to disable, in which case default_data_alignment\n"
|
||||
"is used to align the first PE in units of MiB.\n"
|
||||
"This setting is overridden by the --dataalignment option.\n")
|
||||
"This setting is overriden by the --dataalignment option.\n")
|
||||
|
||||
cfg(devices_data_alignment_offset_detection_CFG, "data_alignment_offset_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DATA_ALIGNMENT_OFFSET_DETECTION, vsn(2, 2, 50), NULL, 0, NULL,
|
||||
"Shift the start of an aligned PV data area based on sysfs information.\n"
|
||||
@@ -467,7 +441,7 @@ cfg(devices_data_alignment_offset_detection_CFG, "data_alignment_offset_detectio
|
||||
"partitioning will have an alignment_offset of 3584 bytes (sector 7\n"
|
||||
"is the lowest aligned logical block, the 4KiB sectors start at\n"
|
||||
"LBA -1, and consequently sector 63 is aligned on a 4KiB boundary).\n"
|
||||
"This setting is overridden by the --dataalignmentoffset option.\n")
|
||||
"This setting is overriden by the --dataalignmentoffset option.\n")
|
||||
|
||||
cfg(devices_ignore_suspended_devices_CFG, "ignore_suspended_devices", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_IGNORE_SUSPENDED_DEVICES, vsn(1, 2, 19), NULL, 0, NULL,
|
||||
"Ignore DM devices that have I/O suspended while scanning devices.\n"
|
||||
@@ -493,7 +467,7 @@ cfg(devices_ignore_lvm_mirrors_CFG, "ignore_lvm_mirrors", devices_CFG_SECTION, 0
|
||||
"different way, making them a better choice for VG stacking.\n")
|
||||
|
||||
cfg(devices_disable_after_error_count_CFG, "disable_after_error_count", devices_CFG_SECTION, 0, CFG_TYPE_INT, 0, vsn(2, 2, 75), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg(devices_require_restorefile_with_uuid_CFG, "require_restorefile_with_uuid", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_REQUIRE_RESTOREFILE_WITH_UUID, vsn(2, 2, 73), NULL, 0, NULL,
|
||||
"Allow use of pvcreate --uuid without requiring --restorefile.\n")
|
||||
@@ -594,7 +568,7 @@ cfg(allocation_raid_stripe_all_devices_CFG, "raid_stripe_all_devices", allocatio
|
||||
"stripes to use.\n"
|
||||
"This was the default behaviour until release 2.02.162.\n")
|
||||
|
||||
cfg(allocation_cache_pool_metadata_require_separate_pvs_CFG, "cache_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_CACHE_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 106), NULL, 0, NULL,
|
||||
cfg(allocation_cache_pool_metadata_require_separate_pvs_CFG, "cache_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_BOOL, DEFAULT_CACHE_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 106), NULL, 0, NULL,
|
||||
"Cache pool metadata and data will always use different PVs.\n")
|
||||
|
||||
cfg(allocation_cache_pool_cachemode_CFG, "cache_pool_cachemode", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_CACHE_MODE, vsn(2, 2, 113), NULL, vsn(2, 2, 128),
|
||||
@@ -651,13 +625,8 @@ cfg(allocation_cache_pool_max_chunks_CFG, "cache_pool_max_chunks", allocation_CF
|
||||
"For cache target v1.9 the recommended maximumm is 1000000 chunks.\n"
|
||||
"Using cache pool with more chunks may degrade cache performance.\n")
|
||||
|
||||
cfg(allocation_thin_pool_metadata_require_separate_pvs_CFG, "thin_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 89), NULL, 0, NULL,
|
||||
"Thin pool metadata and data will always use different PVs.\n")
|
||||
|
||||
cfg(allocation_thin_pool_crop_metadata_CFG, "thin_pool_crop_metadata", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_CROP_METADATA, vsn(2, 3, 12), NULL, 0, NULL,
|
||||
"Older version of lvm2 cropped pool's metadata size to 15.81 GiB.\n"
|
||||
"This is slightly less then the actual maximum 15.88 GiB.\n"
|
||||
"For compatibility with older version and use of cropped size set to 1.\n")
|
||||
cfg(allocation_thin_pool_metadata_require_separate_pvs_CFG, "thin_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 89), NULL, 0, NULL,
|
||||
"Thin pool metdata and data will always use different PVs.\n")
|
||||
|
||||
cfg(allocation_thin_pool_zero_CFG, "thin_pool_zero", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_ZERO, vsn(2, 2, 99), NULL, 0, NULL,
|
||||
"Thin pool data chunks are zeroed before they are first used.\n"
|
||||
@@ -688,9 +657,6 @@ cfg(allocation_thin_pool_chunk_size_policy_CFG, "thin_pool_chunk_size_policy", a
|
||||
" 512KiB.\n"
|
||||
"#\n")
|
||||
|
||||
cfg(allocation_zero_metadata_CFG, "zero_metadata", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_ZERO_METADATA, vsn(2, 3, 10), NULL, 0, NULL,
|
||||
"Zero whole metadata area before use with thin or cache pool.\n")
|
||||
|
||||
cfg_runtime(allocation_thin_pool_chunk_size_CFG, "thin_pool_chunk_size", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(2, 2, 99), 0, NULL,
|
||||
"The minimal chunk size in KiB for thin pool volumes.\n"
|
||||
"Larger chunk sizes may improve performance for plain thin volumes,\n"
|
||||
@@ -974,13 +940,13 @@ cfg(global_activation_CFG, "activation", global_CFG_SECTION, 0, CFG_TYPE_BOOL, D
|
||||
"the error messages.\n")
|
||||
|
||||
cfg(global_fallback_to_lvm1_CFG, "fallback_to_lvm1", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(1, 0, 18), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg(global_format_CFG, "format", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_FORMAT, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg_array(global_format_libraries_CFG, "format_libraries", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.")
|
||||
|
||||
cfg_array(global_segment_libraries_CFG, "segment_libraries", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL, vsn(2, 3, 3), NULL, NULL)
|
||||
|
||||
@@ -991,16 +957,16 @@ cfg(global_etc_CFG, "etc", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_ETC_D
|
||||
"Location of /etc system configuration directory.\n")
|
||||
|
||||
cfg(global_locking_type_CFG, "locking_type", global_CFG_SECTION, 0, CFG_TYPE_INT, 1, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.")
|
||||
|
||||
cfg(global_wait_for_locks_CFG, "wait_for_locks", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_WAIT_FOR_LOCKS, vsn(2, 2, 50), NULL, 0, NULL,
|
||||
"When disabled, fail if a lock request would block.\n")
|
||||
|
||||
cfg(global_fallback_to_clustered_locking_CFG, "fallback_to_clustered_locking", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING, vsn(2, 2, 42), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg(global_fallback_to_local_locking_CFG, "fallback_to_local_locking", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_FALLBACK_TO_LOCAL_LOCKING, vsn(2, 2, 42), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg(global_locking_dir_CFG, "locking_dir", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_LOCK_DIR, vsn(1, 0, 0), "@DEFAULT_LOCK_DIR@", 0, NULL,
|
||||
"Directory to use for LVM command file locks.\n"
|
||||
@@ -1013,13 +979,14 @@ cfg(global_prioritise_write_locks_CFG, "prioritise_write_locks", global_CFG_SECT
|
||||
"a volume group's metadata, instead of always granting the read-only\n"
|
||||
"requests immediately, delay them to allow the read-write requests to\n"
|
||||
"be serviced. Without this setting, write access may be stalled by a\n"
|
||||
"high volume of read-only requests. This option only affects file locks.\n")
|
||||
"high volume of read-only requests. This option only affects\n"
|
||||
"locking_type 1 viz. local file-based locking.\n")
|
||||
|
||||
cfg(global_library_dir_CFG, "library_dir", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Search this directory first for shared libraries.\n")
|
||||
|
||||
cfg(global_locking_library_CFG, "locking_library", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_LOCKING_LIB, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg(global_abort_on_internal_errors_CFG, "abort_on_internal_errors", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ABORT_ON_INTERNAL_ERRORS, vsn(2, 2, 57), NULL, 0, NULL,
|
||||
"Abort a command that encounters an internal error.\n"
|
||||
@@ -1027,7 +994,7 @@ cfg(global_abort_on_internal_errors_CFG, "abort_on_internal_errors", global_CFG_
|
||||
"encountered the internal error. Please only enable for debugging.\n")
|
||||
|
||||
cfg(global_detect_internal_vg_cache_corruption_CFG, "detect_internal_vg_cache_corruption", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 96), NULL, vsn(2, 2, 174), NULL,
|
||||
NULL)
|
||||
"No longer used.\n")
|
||||
|
||||
cfg(global_metadata_read_only_CFG, "metadata_read_only", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_METADATA_READ_ONLY, vsn(2, 2, 75), NULL, 0, NULL,
|
||||
"No operations that change on-disk metadata are permitted.\n"
|
||||
@@ -1061,7 +1028,7 @@ cfg(global_mirror_segtype_default_CFG, "mirror_segtype_default", global_CFG_SECT
|
||||
" fashion in a cluster.\n"
|
||||
"#\n")
|
||||
|
||||
cfg(global_support_mirrored_mirror_log_CFG, "support_mirrored_mirror_log", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(2, 3, 2), NULL, 0, NULL,
|
||||
cfg(global_support_mirrored_mirror_log_CFG, "support_mirrored_mirror_log", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 3, 2), NULL, 0, NULL,
|
||||
"Enable mirrored 'mirror' log type for testing.\n"
|
||||
"#\n"
|
||||
"This type is deprecated to create or convert to but can\n"
|
||||
@@ -1115,23 +1082,20 @@ cfg(global_lvdisplay_shows_full_device_path_CFG, "lvdisplay_shows_full_device_pa
|
||||
"Previously this was always shown as /dev/vgname/lvname even when that\n"
|
||||
"was never a valid path in the /dev filesystem.\n")
|
||||
|
||||
cfg(global_event_activation_CFG, "event_activation", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 1, vsn(2, 3, 1), 0, 0, NULL,
|
||||
cfg(global_event_activation_CFG, "event_activation", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(2, 3, 1), 0, 0, NULL,
|
||||
"Activate LVs based on system-generated device events.\n"
|
||||
"When a PV appears on the system, a system-generated uevent triggers\n"
|
||||
"the lvm2-pvscan service which runs the pvscan --cache -aay command.\n"
|
||||
"If the new PV completes a VG, pvscan autoactivates LVs in the VG.\n"
|
||||
"When event_activation is disabled, the lvm2-activation services are\n"
|
||||
"generated and run at fixed points during system startup. These\n"
|
||||
"services run vgchange -aay to autoactivate LVs in VGs that happen\n"
|
||||
"to be present at that point in time.\n"
|
||||
"See the --setautoactivation option or the auto_activation_volume_list\n"
|
||||
"setting to configure autoactivation for specific VGs or LVs.\n")
|
||||
"When a device appears on the system, a system-generated event runs\n"
|
||||
"the pvscan command to activate LVs if the new PV completes the VG.\n"
|
||||
"Use auto_activation_volume_list to select which LVs should be\n"
|
||||
"activated from these events (the default is all.)\n"
|
||||
"When event_activation is disabled, the system will generally run\n"
|
||||
"a direct activation command to activate LVs in complete VGs.\n")
|
||||
|
||||
cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 93), 0, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg(global_lvmetad_update_wait_time_CFG, "lvmetad_update_wait_time", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, 0, vsn(2, 2, 151), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg(global_use_aio_CFG, "use_aio", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_USE_AIO, vsn(2, 2, 183), NULL, 0, NULL,
|
||||
"Use async I/O when reading and writing devices.\n")
|
||||
@@ -1155,15 +1119,6 @@ cfg(global_sanlock_lv_extend_CFG, "sanlock_lv_extend", global_CFG_SECTION, CFG_D
|
||||
"and can cause lvcreate to fail. Applicable only if LVM is compiled\n"
|
||||
"with lockd support\n")
|
||||
|
||||
cfg(global_lvmlockctl_kill_command_CFG, "lvmlockctl_kill_command", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, "", vsn(2, 3, 12), NULL, 0, NULL,
|
||||
"The command that lvmlockctl --kill should use to force LVs offline.\n"
|
||||
"The lvmlockctl --kill command is run when a shared VG has lost\n"
|
||||
"access to locks (e.g. when sanlock has lost access to storage.)\n"
|
||||
"An empty string means that there will be no automatic attempt by\n"
|
||||
"lvmlockctl --kill to forcibly shut down LVs in the VG, and the user\n"
|
||||
"can manually intervene as described in lvmlockd(8).\n"
|
||||
"The VG name will be appended to the command specified here.\n")
|
||||
|
||||
cfg(global_thin_check_executable_CFG, "thin_check_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, THIN_CHECK_CMD, vsn(2, 2, 94), "@THIN_CHECK_CMD@", 0, NULL,
|
||||
"The full path to the thin_check command.\n"
|
||||
"LVM uses this command to check that a thin metadata device is in a\n"
|
||||
@@ -1249,15 +1204,6 @@ cfg(global_vdo_format_executable_CFG, "vdo_format_executable", global_CFG_SECTIO
|
||||
cfg_array(global_vdo_format_options_CFG, "vdo_format_options", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_VDO_FORMAT_OPTIONS_CONFIG, VDO_1ST_VSN, NULL, 0, NULL,
|
||||
"List of options passed added to standard vdoformat command.\n")
|
||||
|
||||
cfg_array(global_vdo_disabled_features_CFG, "vdo_disabled_features", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 3, 11), NULL, 0, NULL,
|
||||
"Features to not use in the vdo driver.\n"
|
||||
"This can be helpful for testing, or to avoid using a feature that is\n"
|
||||
"causing problems. Features include: online_rename\n"
|
||||
"#\n"
|
||||
"Example\n"
|
||||
"vdo_disabled_features = [ \"online_rename\" ]\n"
|
||||
"#\n")
|
||||
|
||||
cfg(global_fsadm_executable_CFG, "fsadm_executable", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_FSADM_PATH, vsn(2, 2, 170), "@FSADM_PATH@", 0, NULL,
|
||||
"The full path to the fsadm command.\n"
|
||||
"LVM uses this command to help with lvresize -r operations.\n")
|
||||
@@ -1326,7 +1272,7 @@ cfg(global_io_memory_size_CFG, "io_memory_size", global_CFG_SECTION, CFG_DEFAULT
|
||||
|
||||
cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_UDEV_SYNC, vsn(2, 2, 51), NULL, 0, NULL,
|
||||
"Use udev notifications to synchronize udev and LVM.\n"
|
||||
"The --noudevsync option overrides this setting.\n"
|
||||
"The --nodevsync option overrides this setting.\n"
|
||||
"When disabled, LVM commands will not wait for notifications from\n"
|
||||
"udev, but continue irrespective of any possible udev processing in\n"
|
||||
"the background. Only use this if udev is not running or has rules\n"
|
||||
@@ -1340,7 +1286,7 @@ cfg(activation_udev_rules_CFG, "udev_rules", activation_CFG_SECTION, 0, CFG_TYPE
|
||||
"active LVs itself. Manual intervention may be required if this\n"
|
||||
"setting is changed while LVs are active.\n")
|
||||
|
||||
cfg(activation_verify_udev_operations_CFG, "verify_udev_operations", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_VERIFY_UDEV_OPERATIONS, vsn(2, 2, 86), NULL, 0, NULL,
|
||||
cfg(activation_verify_udev_operations_CFG, "verify_udev_operations", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_VERIFY_UDEV_OPERATIONS, vsn(2, 2, 86), NULL, 0, NULL,
|
||||
"Use extra checks in LVM to verify udev operations.\n"
|
||||
"This enables additional checks (and if necessary, repairs) on entries\n"
|
||||
"in the device directory after udev has completed processing its\n"
|
||||
@@ -1361,21 +1307,21 @@ cfg(activation_missing_stripe_filler_CFG, "missing_stripe_filler", activation_CF
|
||||
"other than 'error' with mirrored or snapshotted volumes is likely to\n"
|
||||
"result in data corruption.\n")
|
||||
|
||||
cfg(activation_use_linear_target_CFG, "use_linear_target", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_USE_LINEAR_TARGET, vsn(2, 2, 89), NULL, 0, NULL,
|
||||
cfg(activation_use_linear_target_CFG, "use_linear_target", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_USE_LINEAR_TARGET, vsn(2, 2, 89), NULL, 0, NULL,
|
||||
"Use the linear target to optimize single stripe LVs.\n"
|
||||
"When disabled, the striped target is used. The linear target is an\n"
|
||||
"optimised version of the striped target that only handles a single\n"
|
||||
"stripe.\n")
|
||||
|
||||
cfg(activation_reserved_stack_CFG, "reserved_stack", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_RESERVED_STACK, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(activation_reserved_stack_CFG, "reserved_stack", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_RESERVED_STACK, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Stack size in KiB to reserve for use while devices are suspended.\n"
|
||||
"Insufficent reserve risks I/O deadlock during device suspension.\n")
|
||||
|
||||
cfg(activation_reserved_memory_CFG, "reserved_memory", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_RESERVED_MEMORY, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(activation_reserved_memory_CFG, "reserved_memory", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_RESERVED_MEMORY, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Memory size in KiB to reserve for use while devices are suspended.\n"
|
||||
"Insufficent reserve risks I/O deadlock during device suspension.\n")
|
||||
|
||||
cfg(activation_process_priority_CFG, "process_priority", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_PROCESS_PRIORITY, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(activation_process_priority_CFG, "process_priority", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_PROCESS_PRIORITY, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Nice value used while devices are suspended.\n"
|
||||
"Use a high priority so that LVs are suspended\n"
|
||||
"for the shortest possible time.\n")
|
||||
@@ -1405,22 +1351,22 @@ cfg_array(activation_volume_list_CFG, "volume_list", activation_CFG_SECTION, CFG
|
||||
"#\n")
|
||||
|
||||
cfg_array(activation_auto_activation_volume_list_CFG, "auto_activation_volume_list", activation_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 97), NULL, 0, NULL,
|
||||
"A list of VGs or LVs that should be autoactivated.\n"
|
||||
"Autoactivation is an activation command run with -aay,\n"
|
||||
"i.e. vgchange -aay, lvchange -aay, or pvscan --cache -aay.\n"
|
||||
"When this list is defined, an autoactivation command will only\n"
|
||||
"activate LVs included in the list. If this list is undefined,\n"
|
||||
"it has no effect. If this list is defined but empty, then no\n"
|
||||
"LVs will be autoactivated. LVs can be included in the list by\n"
|
||||
"LV name, VG name (applies to all LVs in the VG), or tag name.\n"
|
||||
"VGs and LVs can also have an autoactivation property set in\n"
|
||||
"metadata, see --setautoactivation. LVs included in this list\n"
|
||||
"will not be autoactivated if the VG or LV autoactivation\n"
|
||||
"property is disabled (see vgs or lvs \"-o autoactivation\").\n"
|
||||
"The volume_list setting and the \"activation skip\" property\n"
|
||||
"also apply to autoactivation.\n"
|
||||
"The -aay option is meant to be used by activation commands that\n"
|
||||
"are run automatically by the system, e.g. from systemd services.\n"
|
||||
"Only LVs selected by this list are auto-activated.\n"
|
||||
"This list works like volume_list, but it is used only by\n"
|
||||
"auto-activation commands. It does not apply to direct activation\n"
|
||||
"commands. If this list is defined, an LV is only auto-activated\n"
|
||||
"if it matches an entry in this list. If this list is undefined, it\n"
|
||||
"imposes no limits on LV auto-activation (all are allowed.) If this\n"
|
||||
"list is defined and empty, i.e. \"[]\", then no LVs are selected for\n"
|
||||
"auto-activation. An LV that is selected by this list for\n"
|
||||
"auto-activation, must also be selected by volume_list (if defined)\n"
|
||||
"before it is activated. Auto-activation is an activation command that\n"
|
||||
"includes the 'a' argument: --activate ay or -a ay. The 'a' (auto)\n"
|
||||
"argument for auto-activation is meant to be used by activation\n"
|
||||
"commands that are run automatically by the system, as opposed to LVM\n"
|
||||
"commands run directly by a user. A user may also use the 'a' flag\n"
|
||||
"directly to perform auto-activation. Also see pvscan(8) for more\n"
|
||||
"information about auto-activation.\n"
|
||||
"#\n"
|
||||
"Accepted values:\n"
|
||||
" vgname\n"
|
||||
@@ -1484,7 +1430,7 @@ cfg(activation_error_when_full_CFG, "error_when_full", activation_CFG_SECTION, C
|
||||
"thin pool data space is extended. New thin pools are assigned the\n"
|
||||
"behavior defined here.\n")
|
||||
|
||||
cfg(activation_readahead_CFG, "readahead", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_READ_AHEAD, vsn(1, 0, 23), NULL, 0, NULL,
|
||||
cfg(activation_readahead_CFG, "readahead", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_READ_AHEAD, vsn(1, 0, 23), NULL, 0, NULL,
|
||||
"Setting to use when there is no readahead setting in metadata.\n"
|
||||
"#\n"
|
||||
"Accepted values:\n"
|
||||
@@ -1612,7 +1558,7 @@ cfg(activation_thin_pool_autoextend_percent_CFG, "thin_pool_autoextend_percent",
|
||||
"thin_pool_autoextend_percent = 20\n"
|
||||
"#\n")
|
||||
|
||||
cfg(activation_vdo_pool_autoextend_threshold_CFG, "vdo_pool_autoextend_threshold", activation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_POOL_AUTOEXTEND_THRESHOLD, VDO_1ST_VSN, NULL, 0, NULL,
|
||||
cfg(activation_vdo_pool_autoextend_threshold_CFG, "vdo_pool_autoextend_threshold", activation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_INT, DEFAULT_VDO_POOL_AUTOEXTEND_THRESHOLD, VDO_1ST_VSN, NULL, 0, NULL,
|
||||
"Auto-extend a VDO pool when its usage exceeds this percent.\n"
|
||||
"Setting this to 100 disables automatic extension.\n"
|
||||
"The minimum value is 50 (a smaller value is treated as 50.)\n"
|
||||
@@ -1652,7 +1598,7 @@ cfg_array(activation_mlock_filter_CFG, "mlock_filter", activation_CFG_SECTION, C
|
||||
"mlock_filter = [ \"locale/locale-archive\", \"gconv/gconv-modules.cache\" ]\n"
|
||||
"#\n")
|
||||
|
||||
cfg(activation_use_mlockall_CFG, "use_mlockall", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_USE_MLOCKALL, vsn(2, 2, 62), NULL, 0, NULL,
|
||||
cfg(activation_use_mlockall_CFG, "use_mlockall", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_USE_MLOCKALL, vsn(2, 2, 62), NULL, 0, NULL,
|
||||
"Use the old behavior of mlockall to pin all memory.\n"
|
||||
"Prior to version 2.02.62, LVM used mlockall() to pin the whole\n"
|
||||
"process's memory while activating devices.\n")
|
||||
@@ -1662,7 +1608,7 @@ cfg(activation_monitoring_CFG, "monitoring", activation_CFG_SECTION, 0, CFG_TYPE
|
||||
"The --ignoremonitoring option overrides this setting.\n"
|
||||
"When enabled, LVM will ask dmeventd to monitor activated LVs.\n")
|
||||
|
||||
cfg(activation_polling_interval_CFG, "polling_interval", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_INTERVAL, vsn(2, 2, 63), NULL, 0, NULL,
|
||||
cfg(activation_polling_interval_CFG, "polling_interval", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_INTERVAL, vsn(2, 2, 63), NULL, 0, NULL,
|
||||
"Check pvmove or lvconvert progress at this interval (seconds).\n"
|
||||
"When pvmove or lvconvert must wait for the kernel to finish\n"
|
||||
"synchronising or merging data, they check and report progress at\n"
|
||||
@@ -1776,7 +1722,7 @@ cfg(metadata_pvmetadataignore_CFG, "pvmetadataignore", metadata_CFG_SECTION, CFG
|
||||
cfg(metadata_stripesize_CFG, "stripesize", metadata_CFG_SECTION, CFG_ADVANCED | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_STRIPESIZE, vsn(1, 0, 0), NULL, 0, NULL, NULL)
|
||||
|
||||
cfg_array(metadata_dirs_CFG, "dirs", metadata_CFG_SECTION, CFG_ADVANCED | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
"This setting is no longer used.\n")
|
||||
|
||||
cfg_section(metadata_disk_areas_CFG_SUBSECTION, "disk_areas", metadata_CFG_SECTION, CFG_UNSUPPORTED | CFG_DEFAULT_COMMENTED, vsn(1, 0, 0), vsn(2, 3, 0), NULL, NULL)
|
||||
cfg_section(disk_area_CFG_SUBSECTION, "disk_area", metadata_disk_areas_CFG_SUBSECTION, CFG_NAME_VARIABLE | CFG_UNSUPPORTED | CFG_DEFAULT_COMMENTED, vsn(1, 0, 0), vsn(2, 3, 0), NULL, NULL)
|
||||
@@ -2101,7 +2047,7 @@ cfg(report_two_word_unknown_device_CFG, "two_word_unknown_device", report_CFG_SE
|
||||
"Use the two words 'unknown device' in place of '[unknown]'.\n"
|
||||
"This is displayed when the device for a PV is not known.\n")
|
||||
|
||||
cfg(dmeventd_mirror_library_CFG, "mirror_library", dmeventd_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_DMEVENTD_MIRROR_LIB, vsn(1, 2, 3), NULL, 0, NULL,
|
||||
cfg(dmeventd_mirror_library_CFG, "mirror_library", dmeventd_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_DMEVENTD_MIRROR_LIB, vsn(1, 2, 3), NULL, 0, NULL,
|
||||
"The library dmeventd uses when monitoring a mirror device.\n"
|
||||
"libdevmapper-event-lvm2mirror.so attempts to recover from\n"
|
||||
"failures. It removes failed devices from a volume group and\n"
|
||||
@@ -2110,13 +2056,13 @@ cfg(dmeventd_mirror_library_CFG, "mirror_library", dmeventd_CFG_SECTION, CFG_DEF
|
||||
|
||||
cfg(dmeventd_raid_library_CFG, "raid_library", dmeventd_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_DMEVENTD_RAID_LIB, vsn(2, 2, 87), NULL, 0, NULL, NULL)
|
||||
|
||||
cfg(dmeventd_snapshot_library_CFG, "snapshot_library", dmeventd_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_DMEVENTD_SNAPSHOT_LIB, vsn(1, 2, 26), NULL, 0, NULL,
|
||||
cfg(dmeventd_snapshot_library_CFG, "snapshot_library", dmeventd_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_DMEVENTD_SNAPSHOT_LIB, vsn(1, 2, 26), NULL, 0, NULL,
|
||||
"The library dmeventd uses when monitoring a snapshot device.\n"
|
||||
"libdevmapper-event-lvm2snapshot.so monitors the filling of snapshots\n"
|
||||
"and emits a warning through syslog when the usage exceeds 80%. The\n"
|
||||
"warning is repeated when 85%, 90% and 95% of the snapshot is filled.\n")
|
||||
|
||||
cfg(dmeventd_thin_library_CFG, "thin_library", dmeventd_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_DMEVENTD_THIN_LIB, vsn(2, 2, 89), NULL, 0, NULL,
|
||||
cfg(dmeventd_thin_library_CFG, "thin_library", dmeventd_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_DMEVENTD_THIN_LIB, vsn(2, 2, 89), NULL, 0, NULL,
|
||||
"The library dmeventd uses when monitoring a thin device.\n"
|
||||
"libdevmapper-event-lvm2thin.so monitors the filling of a pool\n"
|
||||
"and emits a warning through syslog when the usage exceeds 80%. The\n"
|
||||
|
@@ -118,8 +118,6 @@
|
||||
#define DEFAULT_THIN_REPAIR_OPTION1 ""
|
||||
#define DEFAULT_THIN_REPAIR_OPTIONS_CONFIG "#S" DEFAULT_THIN_REPAIR_OPTION1
|
||||
#define DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS 0
|
||||
#define DEFAULT_THIN_POOL_CROP_METADATA 0
|
||||
#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE_V1_KB (UINT64_C(255) * ((1 << 14) - 64) * 4) /* KB */ /* 0x3f8040 blocks */
|
||||
#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (DM_THIN_MAX_METADATA_SIZE / 2) /* KB */
|
||||
#define DEFAULT_THIN_POOL_MIN_METADATA_SIZE 2048 /* KB */
|
||||
#define DEFAULT_THIN_POOL_OPTIMAL_METADATA_SIZE (128 * 1024) /* KB */
|
||||
@@ -131,7 +129,6 @@
|
||||
#define DEFAULT_THIN_POOL_DISCARDS "passdown"
|
||||
#define DEFAULT_THIN_POOL_ZERO 1
|
||||
#define DEFAULT_POOL_METADATA_SPARE 1 /* thin + cache */
|
||||
#define DEFAULT_ZERO_METADATA 1 /* thin + cache */
|
||||
|
||||
#ifdef CACHE_CHECK_NEEDS_CHECK
|
||||
# define DEFAULT_CACHE_CHECK_OPTION1 "-q"
|
||||
@@ -323,9 +320,4 @@
|
||||
|
||||
#define DEFAULT_MD_COMPONENT_CHECKS "auto"
|
||||
|
||||
#define DEFAULT_USE_DEVICES_FILE 0
|
||||
#define DEFAULT_DEVICES_FILE "system.devices"
|
||||
|
||||
#define DEFAULT_SEARCH_FOR_DEVNAMES "auto"
|
||||
|
||||
#endif /* _LVM_DEFAULTS_H */
|
||||
|
@@ -218,7 +218,7 @@ struct dm_list *str_to_str_list(struct dm_pool *mem, const char *str,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p1 = str;
|
||||
p1 = p2 = str;
|
||||
while (*p1) {
|
||||
if (!(p2 = strstr(p1, delim)))
|
||||
next = p2 = str + strlen(str);
|
||||
|
@@ -39,32 +39,32 @@ static uint64_t _min(uint64_t lhs, uint64_t rhs)
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
void bcache_prefetch_bytes(struct bcache *cache, int di, uint64_t start, size_t len)
|
||||
void bcache_prefetch_bytes(struct bcache *cache, int fd, uint64_t start, size_t len)
|
||||
{
|
||||
block_address bb, be;
|
||||
|
||||
byte_range_to_block_range(cache, start, len, &bb, &be);
|
||||
while (bb < be) {
|
||||
bcache_prefetch(cache, di, bb);
|
||||
bcache_prefetch(cache, fd, bb);
|
||||
bb++;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
bool bcache_read_bytes(struct bcache *cache, int di, uint64_t start, size_t len, void *data)
|
||||
bool bcache_read_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, void *data)
|
||||
{
|
||||
struct block *b;
|
||||
block_address bb, be;
|
||||
uint64_t block_size = bcache_block_sectors(cache) << SECTOR_SHIFT;
|
||||
uint64_t block_offset = start % block_size;
|
||||
|
||||
bcache_prefetch_bytes(cache, di, start, len);
|
||||
bcache_prefetch_bytes(cache, fd, start, len);
|
||||
|
||||
byte_range_to_block_range(cache, start, len, &bb, &be);
|
||||
|
||||
for (; bb != be; bb++) {
|
||||
if (!bcache_get(cache, di, bb, 0, &b))
|
||||
if (!bcache_get(cache, fd, bb, 0, &b))
|
||||
return false;
|
||||
|
||||
size_t blen = _min(block_size - block_offset, len);
|
||||
@@ -79,21 +79,6 @@ bool bcache_read_bytes(struct bcache *cache, int di, uint64_t start, size_t len,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bcache_invalidate_bytes(struct bcache *cache, int di, uint64_t start, size_t len)
|
||||
{
|
||||
block_address bb, be;
|
||||
bool result = true;
|
||||
|
||||
byte_range_to_block_range(cache, start, len, &bb, &be);
|
||||
|
||||
for (; bb != be; bb++) {
|
||||
if (!bcache_invalidate(cache, di, bb))
|
||||
result = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
// Writing bytes and zeroing bytes are very similar, so we factor out
|
||||
@@ -101,8 +86,8 @@ bool bcache_invalidate_bytes(struct bcache *cache, int di, uint64_t start, size_
|
||||
|
||||
struct updater;
|
||||
|
||||
typedef bool (*partial_update_fn)(struct updater *u, int di, block_address bb, uint64_t offset, size_t len);
|
||||
typedef bool (*whole_update_fn)(struct updater *u, int di, block_address bb, block_address be);
|
||||
typedef bool (*partial_update_fn)(struct updater *u, int fd, block_address bb, uint64_t offset, size_t len);
|
||||
typedef bool (*whole_update_fn)(struct updater *u, int fd, block_address bb, block_address be);
|
||||
|
||||
struct updater {
|
||||
struct bcache *cache;
|
||||
@@ -111,7 +96,7 @@ struct updater {
|
||||
void *data;
|
||||
};
|
||||
|
||||
static bool _update_bytes(struct updater *u, int di, uint64_t start, size_t len)
|
||||
static bool _update_bytes(struct updater *u, int fd, uint64_t start, size_t len)
|
||||
{
|
||||
struct bcache *cache = u->cache;
|
||||
block_address bb, be;
|
||||
@@ -124,12 +109,12 @@ static bool _update_bytes(struct updater *u, int di, uint64_t start, size_t len)
|
||||
// If the last block is partial, we will require a read, so let's
|
||||
// prefetch it.
|
||||
if ((start + len) % block_size)
|
||||
bcache_prefetch(cache, di, (start + len) / block_size);
|
||||
bcache_prefetch(cache, fd, (start + len) / block_size);
|
||||
|
||||
// First block may be partial
|
||||
if (block_offset) {
|
||||
size_t blen = _min(block_size - block_offset, len);
|
||||
if (!u->partial_fn(u, di, bb, block_offset, blen))
|
||||
if (!u->partial_fn(u, fd, bb, block_offset, blen))
|
||||
return false;
|
||||
|
||||
len -= blen;
|
||||
@@ -141,7 +126,7 @@ static bool _update_bytes(struct updater *u, int di, uint64_t start, size_t len)
|
||||
|
||||
// Now we write out a set of whole blocks
|
||||
nr_whole = len / block_size;
|
||||
if (!u->whole_fn(u, di, bb, bb + nr_whole))
|
||||
if (!u->whole_fn(u, fd, bb, bb + nr_whole))
|
||||
return false;
|
||||
|
||||
bb += nr_whole;
|
||||
@@ -151,17 +136,17 @@ static bool _update_bytes(struct updater *u, int di, uint64_t start, size_t len)
|
||||
return true;
|
||||
|
||||
// Finally we write a partial end block
|
||||
return u->partial_fn(u, di, bb, 0, len);
|
||||
return u->partial_fn(u, fd, bb, 0, len);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
static bool _write_partial(struct updater *u, int di, block_address bb,
|
||||
static bool _write_partial(struct updater *u, int fd, block_address bb,
|
||||
uint64_t offset, size_t len)
|
||||
{
|
||||
struct block *b;
|
||||
|
||||
if (!bcache_get(u->cache, di, bb, GF_DIRTY, &b))
|
||||
if (!bcache_get(u->cache, fd, bb, GF_DIRTY, &b))
|
||||
return false;
|
||||
|
||||
memcpy(((unsigned char *) b->data) + offset, u->data, len);
|
||||
@@ -171,7 +156,7 @@ static bool _write_partial(struct updater *u, int di, block_address bb,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _write_whole(struct updater *u, int di, block_address bb, block_address be)
|
||||
static bool _write_whole(struct updater *u, int fd, block_address bb, block_address be)
|
||||
{
|
||||
struct block *b;
|
||||
uint64_t block_size = bcache_block_sectors(u->cache) << SECTOR_SHIFT;
|
||||
@@ -179,7 +164,7 @@ static bool _write_whole(struct updater *u, int di, block_address bb, block_addr
|
||||
for (; bb != be; bb++) {
|
||||
// We don't need to read the block since we are overwriting
|
||||
// it completely.
|
||||
if (!bcache_get(u->cache, di, bb, GF_ZERO, &b))
|
||||
if (!bcache_get(u->cache, fd, bb, GF_ZERO, &b))
|
||||
return false;
|
||||
memcpy(b->data, u->data, block_size);
|
||||
u->data = ((unsigned char *) u->data) + block_size;
|
||||
@@ -189,7 +174,7 @@ static bool _write_whole(struct updater *u, int di, block_address bb, block_addr
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bcache_write_bytes(struct bcache *cache, int di, uint64_t start, size_t len, void *data)
|
||||
bool bcache_write_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, void *data)
|
||||
{
|
||||
struct updater u;
|
||||
|
||||
@@ -198,16 +183,16 @@ bool bcache_write_bytes(struct bcache *cache, int di, uint64_t start, size_t len
|
||||
u.whole_fn = _write_whole;
|
||||
u.data = data;
|
||||
|
||||
return _update_bytes(&u, di, start, len);
|
||||
return _update_bytes(&u, fd, start, len);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
static bool _zero_partial(struct updater *u, int di, block_address bb, uint64_t offset, size_t len)
|
||||
static bool _zero_partial(struct updater *u, int fd, block_address bb, uint64_t offset, size_t len)
|
||||
{
|
||||
struct block *b;
|
||||
|
||||
if (!bcache_get(u->cache, di, bb, GF_DIRTY, &b))
|
||||
if (!bcache_get(u->cache, fd, bb, GF_DIRTY, &b))
|
||||
return false;
|
||||
|
||||
memset(((unsigned char *) b->data) + offset, 0, len);
|
||||
@@ -216,12 +201,12 @@ static bool _zero_partial(struct updater *u, int di, block_address bb, uint64_t
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _zero_whole(struct updater *u, int di, block_address bb, block_address be)
|
||||
static bool _zero_whole(struct updater *u, int fd, block_address bb, block_address be)
|
||||
{
|
||||
struct block *b;
|
||||
|
||||
for (; bb != be; bb++) {
|
||||
if (!bcache_get(u->cache, di, bb, GF_ZERO, &b))
|
||||
if (!bcache_get(u->cache, fd, bb, GF_ZERO, &b))
|
||||
return false;
|
||||
bcache_put(b);
|
||||
}
|
||||
@@ -229,7 +214,7 @@ static bool _zero_whole(struct updater *u, int di, block_address bb, block_addre
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bcache_zero_bytes(struct bcache *cache, int di, uint64_t start, size_t len)
|
||||
bool bcache_zero_bytes(struct bcache *cache, int fd, uint64_t start, size_t len)
|
||||
{
|
||||
struct updater u;
|
||||
|
||||
@@ -238,17 +223,17 @@ bool bcache_zero_bytes(struct bcache *cache, int di, uint64_t start, size_t len)
|
||||
u.whole_fn = _zero_whole;
|
||||
u.data = NULL;
|
||||
|
||||
return _update_bytes(&u, di, start, len);
|
||||
return _update_bytes(&u, fd, start, len);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
static bool _set_partial(struct updater *u, int di, block_address bb, uint64_t offset, size_t len)
|
||||
static bool _set_partial(struct updater *u, int fd, block_address bb, uint64_t offset, size_t len)
|
||||
{
|
||||
struct block *b;
|
||||
uint8_t val = *((uint8_t *) u->data);
|
||||
|
||||
if (!bcache_get(u->cache, di, bb, GF_DIRTY, &b))
|
||||
if (!bcache_get(u->cache, fd, bb, GF_DIRTY, &b))
|
||||
return false;
|
||||
|
||||
memset(((unsigned char *) b->data) + offset, val, len);
|
||||
@@ -257,14 +242,14 @@ static bool _set_partial(struct updater *u, int di, block_address bb, uint64_t o
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _set_whole(struct updater *u, int di, block_address bb, block_address be)
|
||||
static bool _set_whole(struct updater *u, int fd, block_address bb, block_address be)
|
||||
{
|
||||
struct block *b;
|
||||
uint8_t val = *((uint8_t *) u->data);
|
||||
uint64_t len = bcache_block_sectors(u->cache) * 512;
|
||||
|
||||
for (; bb != be; bb++) {
|
||||
if (!bcache_get(u->cache, di, bb, GF_ZERO, &b))
|
||||
if (!bcache_get(u->cache, fd, bb, GF_ZERO, &b))
|
||||
return false;
|
||||
memset((unsigned char *) b->data, val, len);
|
||||
bcache_put(b);
|
||||
@@ -273,7 +258,7 @@ static bool _set_whole(struct updater *u, int di, block_address bb, block_addres
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bcache_set_bytes(struct bcache *cache, int di, uint64_t start, size_t len, uint8_t val)
|
||||
bool bcache_set_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, uint8_t val)
|
||||
{
|
||||
struct updater u;
|
||||
|
||||
@@ -282,6 +267,6 @@ bool bcache_set_bytes(struct bcache *cache, int di, uint64_t start, size_t len,
|
||||
u.whole_fn = _set_whole;
|
||||
u.data = &val;
|
||||
|
||||
return _update_bytes(&u, di, start, len);
|
||||
return _update_bytes(&u, fd, start, len);
|
||||
}
|
||||
|
||||
|
@@ -33,16 +33,11 @@
|
||||
|
||||
#define SECTOR_SHIFT 9L
|
||||
|
||||
#define FD_TABLE_INC 1024
|
||||
static int _fd_table_size;
|
||||
static int *_fd_table;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
static void log_sys_warn(const char *call)
|
||||
{
|
||||
log_warn("WARNING: %s failed: %s.", call, strerror(errno));
|
||||
log_warn("%s failed: %s", call, strerror(errno));
|
||||
}
|
||||
|
||||
// Assumes the list is not empty.
|
||||
@@ -66,17 +61,23 @@ struct control_block {
|
||||
struct cb_set {
|
||||
struct dm_list free;
|
||||
struct dm_list allocated;
|
||||
struct control_block vec[];
|
||||
struct control_block *vec;
|
||||
} control_block_set;
|
||||
|
||||
static struct cb_set *_cb_set_create(unsigned nr)
|
||||
{
|
||||
unsigned i;
|
||||
struct cb_set *cbs = malloc(sizeof(*cbs) + nr * sizeof(*cbs->vec));
|
||||
int i;
|
||||
struct cb_set *cbs = malloc(sizeof(*cbs));
|
||||
|
||||
if (!cbs)
|
||||
return NULL;
|
||||
|
||||
cbs->vec = malloc(nr * sizeof(*cbs->vec));
|
||||
if (!cbs->vec) {
|
||||
free(cbs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dm_list_init(&cbs->free);
|
||||
dm_list_init(&cbs->allocated);
|
||||
|
||||
@@ -92,10 +93,11 @@ static void _cb_set_destroy(struct cb_set *cbs)
|
||||
// never be in flight IO.
|
||||
if (!dm_list_empty(&cbs->allocated)) {
|
||||
// bail out
|
||||
log_warn("WARNING: async io still in flight.");
|
||||
log_error("async io still in flight");
|
||||
return;
|
||||
}
|
||||
|
||||
free(cbs->vec);
|
||||
free(cbs);
|
||||
}
|
||||
|
||||
@@ -153,11 +155,11 @@ static void _async_destroy(struct io_engine *ioe)
|
||||
free(e);
|
||||
}
|
||||
|
||||
static int _last_byte_di;
|
||||
static int _last_byte_fd;
|
||||
static uint64_t _last_byte_offset;
|
||||
static int _last_byte_sector_size;
|
||||
|
||||
static bool _async_issue(struct io_engine *ioe, enum dir d, int di,
|
||||
static bool _async_issue(struct io_engine *ioe, enum dir d, int fd,
|
||||
sector_t sb, sector_t se, void *data, void *context)
|
||||
{
|
||||
int r;
|
||||
@@ -181,7 +183,7 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int di,
|
||||
/*
|
||||
* If bcache block goes past where lvm wants to write, then clamp it.
|
||||
*/
|
||||
if ((d == DIR_WRITE) && _last_byte_offset && (di == _last_byte_di)) {
|
||||
if ((d == DIR_WRITE) && _last_byte_offset && (fd == _last_byte_fd)) {
|
||||
if (offset > _last_byte_offset) {
|
||||
log_error("Limit write at %llu len %llu beyond last byte %llu",
|
||||
(unsigned long long)offset,
|
||||
@@ -266,7 +268,7 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int di,
|
||||
|
||||
memset(&cb->cb, 0, sizeof(cb->cb));
|
||||
|
||||
cb->cb.aio_fildes = (int) _fd_table[di];
|
||||
cb->cb.aio_fildes = (int) fd;
|
||||
cb->cb.u.c.buf = data;
|
||||
cb->cb.u.c.offset = offset;
|
||||
cb->cb.u.c.nbytes = nbytes;
|
||||
@@ -274,15 +276,13 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int di,
|
||||
|
||||
#if 0
|
||||
if (d == DIR_READ) {
|
||||
log_debug("io R off %llu bytes %llu di %d fd %d",
|
||||
log_debug("io R off %llu bytes %llu",
|
||||
(unsigned long long)cb->cb.u.c.offset,
|
||||
(unsigned long long)cb->cb.u.c.nbytes,
|
||||
di, _fd_table[di]);
|
||||
(unsigned long long)cb->cb.u.c.nbytes);
|
||||
} else {
|
||||
log_debug("io W off %llu bytes %llu di %d fd %d",
|
||||
log_debug("io W off %llu bytes %llu",
|
||||
(unsigned long long)cb->cb.u.c.offset,
|
||||
(unsigned long long)cb->cb.u.c.nbytes,
|
||||
di, _fd_table[di]);
|
||||
(unsigned long long)cb->cb.u.c.nbytes);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -318,7 +318,9 @@ static bool _async_wait(struct io_engine *ioe, io_complete_fn fn)
|
||||
struct async_engine *e = _to_async(ioe);
|
||||
|
||||
memset(&event, 0, sizeof(event));
|
||||
r = io_getevents(e->aio_context, 1, MAX_EVENT, event, NULL);
|
||||
do {
|
||||
r = io_getevents(e->aio_context, 1, MAX_EVENT, event, NULL);
|
||||
} while (r == -EINTR);
|
||||
|
||||
if (r < 0) {
|
||||
log_sys_warn("io_getevents");
|
||||
@@ -412,7 +414,7 @@ static void _sync_destroy(struct io_engine *ioe)
|
||||
free(e);
|
||||
}
|
||||
|
||||
static bool _sync_issue(struct io_engine *ioe, enum dir d, int di,
|
||||
static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd,
|
||||
sector_t sb, sector_t se, void *data, void *context)
|
||||
{
|
||||
int rv;
|
||||
@@ -428,7 +430,7 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int di,
|
||||
}
|
||||
|
||||
where = sb * 512;
|
||||
off = lseek(_fd_table[di], where, SEEK_SET);
|
||||
off = lseek(fd, where, SEEK_SET);
|
||||
if (off == (off_t) -1) {
|
||||
log_warn("Device seek error %d for offset %llu", errno, (unsigned long long)where);
|
||||
free(io);
|
||||
@@ -443,7 +445,7 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int di,
|
||||
/*
|
||||
* If bcache block goes past where lvm wants to write, then clamp it.
|
||||
*/
|
||||
if ((d == DIR_WRITE) && _last_byte_offset && (di == _last_byte_di)) {
|
||||
if ((d == DIR_WRITE) && _last_byte_offset && (fd == _last_byte_fd)) {
|
||||
uint64_t offset = where;
|
||||
uint64_t nbytes = len;
|
||||
sector_t limit_nbytes = 0;
|
||||
@@ -513,7 +515,6 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int di,
|
||||
(unsigned long long)limit_nbytes,
|
||||
(unsigned long long)extra_nbytes,
|
||||
(unsigned long long)_last_byte_sector_size);
|
||||
free(io);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -524,9 +525,9 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int di,
|
||||
|
||||
while (pos < len) {
|
||||
if (d == DIR_READ)
|
||||
rv = read(_fd_table[di], (char *)data + pos, len - pos);
|
||||
rv = read(fd, (char *)data + pos, len - pos);
|
||||
else
|
||||
rv = write(_fd_table[di], (char *)data + pos, len - pos);
|
||||
rv = write(fd, (char *)data + pos, len - pos);
|
||||
|
||||
if (rv == -1 && errno == EINTR)
|
||||
continue;
|
||||
@@ -686,7 +687,7 @@ struct bcache {
|
||||
//----------------------------------------------------------------
|
||||
|
||||
struct key_parts {
|
||||
uint32_t di;
|
||||
uint32_t fd;
|
||||
uint64_t b;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
@@ -695,12 +696,12 @@ union key {
|
||||
uint8_t bytes[12];
|
||||
};
|
||||
|
||||
static struct block *_block_lookup(struct bcache *cache, int di, uint64_t i)
|
||||
static struct block *_block_lookup(struct bcache *cache, int fd, uint64_t i)
|
||||
{
|
||||
union key k;
|
||||
union radix_value v;
|
||||
|
||||
k.parts.di = di;
|
||||
k.parts.fd = fd;
|
||||
k.parts.b = i;
|
||||
|
||||
if (radix_tree_lookup(cache->rtree, k.bytes, k.bytes + sizeof(k.bytes), &v))
|
||||
@@ -714,7 +715,7 @@ static bool _block_insert(struct block *b)
|
||||
union key k;
|
||||
union radix_value v;
|
||||
|
||||
k.parts.di = b->di;
|
||||
k.parts.fd = b->fd;
|
||||
k.parts.b = b->index;
|
||||
v.ptr = b;
|
||||
|
||||
@@ -725,7 +726,7 @@ static void _block_remove(struct block *b)
|
||||
{
|
||||
union key k;
|
||||
|
||||
k.parts.di = b->di;
|
||||
k.parts.fd = b->fd;
|
||||
k.parts.b = b->index;
|
||||
|
||||
radix_tree_remove(b->cache->rtree, k.bytes, k.bytes + sizeof(k.bytes));
|
||||
@@ -867,7 +868,7 @@ static void _issue_low_level(struct block *b, enum dir d)
|
||||
|
||||
dm_list_move(&cache->io_pending, &b->list);
|
||||
|
||||
if (!cache->engine->issue(cache->engine, d, b->di, sb, se, b->data, b)) {
|
||||
if (!cache->engine->issue(cache->engine, d, b->fd, sb, se, b->data, b)) {
|
||||
/* FIXME: if io_submit() set an errno, return that instead of EIO? */
|
||||
_complete_io(b, -EIO);
|
||||
return;
|
||||
@@ -943,26 +944,21 @@ static struct block *_find_unused_clean_block(struct bcache *cache)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct block *_new_block(struct bcache *cache, int di, block_address i, bool can_wait)
|
||||
static struct block *_new_block(struct bcache *cache, int fd, block_address i, bool can_wait)
|
||||
{
|
||||
struct block *b;
|
||||
|
||||
b = _alloc_block(cache);
|
||||
while (!b) {
|
||||
while (!b && !dm_list_empty(&cache->clean)) {
|
||||
b = _find_unused_clean_block(cache);
|
||||
if (!b) {
|
||||
if (can_wait) {
|
||||
if (dm_list_empty(&cache->io_pending))
|
||||
_writeback(cache, 16); // FIXME: magic number
|
||||
_wait_all(cache);
|
||||
if (dm_list_size(&cache->errored) >= cache->max_io) {
|
||||
log_debug("bcache no new blocks for di %d index %u with >%d errors.",
|
||||
di, (uint32_t) i, cache->max_io);
|
||||
return NULL;
|
||||
}
|
||||
_wait_io(cache);
|
||||
} else {
|
||||
log_debug("bcache no new blocks for di %d index %u",
|
||||
di, (uint32_t) i);
|
||||
log_debug("bcache no new blocks for fd %d index %u",
|
||||
fd, (uint32_t) i);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -971,7 +967,7 @@ static struct block *_new_block(struct bcache *cache, int di, block_address i, b
|
||||
if (b) {
|
||||
dm_list_init(&b->list);
|
||||
b->flags = 0;
|
||||
b->di = di;
|
||||
b->fd = fd;
|
||||
b->index = i;
|
||||
b->ref_count = 0;
|
||||
b->error = 0;
|
||||
@@ -1017,10 +1013,10 @@ static void _miss(struct bcache *cache, unsigned flags)
|
||||
}
|
||||
|
||||
static struct block *_lookup_or_read_block(struct bcache *cache,
|
||||
int di, block_address i,
|
||||
int fd, block_address i,
|
||||
unsigned flags)
|
||||
{
|
||||
struct block *b = _block_lookup(cache, di, i);
|
||||
struct block *b = _block_lookup(cache, fd, i);
|
||||
|
||||
if (b) {
|
||||
// FIXME: this is insufficient. We need to also catch a read
|
||||
@@ -1045,7 +1041,7 @@ static struct block *_lookup_or_read_block(struct bcache *cache,
|
||||
} else {
|
||||
_miss(cache, flags);
|
||||
|
||||
b = _new_block(cache, di, i, true);
|
||||
b = _new_block(cache, fd, i, true);
|
||||
if (b) {
|
||||
if (flags & GF_ZERO)
|
||||
_zero_block(b);
|
||||
@@ -1090,7 +1086,6 @@ struct bcache *bcache_create(sector_t block_sectors, unsigned nr_cache_blocks,
|
||||
struct bcache *cache;
|
||||
unsigned max_io = engine->max_io(engine);
|
||||
long pgsize = sysconf(_SC_PAGESIZE);
|
||||
int i;
|
||||
|
||||
if (pgsize < 0) {
|
||||
log_warn("WARNING: _SC_PAGESIZE returns negative value.");
|
||||
@@ -1151,18 +1146,6 @@ struct bcache *bcache_create(sector_t block_sectors, unsigned nr_cache_blocks,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_fd_table_size = FD_TABLE_INC;
|
||||
|
||||
if (!(_fd_table = malloc(sizeof(int) * _fd_table_size))) {
|
||||
cache->engine->destroy(cache->engine);
|
||||
radix_tree_destroy(cache->rtree);
|
||||
free(cache);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < _fd_table_size; i++)
|
||||
_fd_table[i] = -1;
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
@@ -1178,9 +1161,6 @@ void bcache_destroy(struct bcache *cache)
|
||||
radix_tree_destroy(cache->rtree);
|
||||
cache->engine->destroy(cache->engine);
|
||||
free(cache);
|
||||
free(_fd_table);
|
||||
_fd_table = NULL;
|
||||
_fd_table_size = 0;
|
||||
}
|
||||
|
||||
sector_t bcache_block_sectors(struct bcache *cache)
|
||||
@@ -1198,13 +1178,13 @@ unsigned bcache_max_prefetches(struct bcache *cache)
|
||||
return cache->max_io;
|
||||
}
|
||||
|
||||
void bcache_prefetch(struct bcache *cache, int di, block_address i)
|
||||
void bcache_prefetch(struct bcache *cache, int fd, block_address i)
|
||||
{
|
||||
struct block *b = _block_lookup(cache, di, i);
|
||||
struct block *b = _block_lookup(cache, fd, i);
|
||||
|
||||
if (!b) {
|
||||
if (cache->nr_io_pending < cache->max_io) {
|
||||
b = _new_block(cache, di, i, false);
|
||||
b = _new_block(cache, fd, i, false);
|
||||
if (b) {
|
||||
cache->prefetches++;
|
||||
_issue_read(b);
|
||||
@@ -1222,15 +1202,12 @@ static void _recycle_block(struct bcache *cache, struct block *b)
|
||||
_free_block(b);
|
||||
}
|
||||
|
||||
bool bcache_get(struct bcache *cache, int di, block_address i,
|
||||
bool bcache_get(struct bcache *cache, int fd, block_address i,
|
||||
unsigned flags, struct block **result)
|
||||
{
|
||||
struct block *b;
|
||||
|
||||
if (di >= _fd_table_size)
|
||||
goto bad;
|
||||
|
||||
b = _lookup_or_read_block(cache, di, i, flags);
|
||||
b = _lookup_or_read_block(cache, fd, i, flags);
|
||||
if (b) {
|
||||
if (b->error) {
|
||||
if (b->io_dir == DIR_READ) {
|
||||
@@ -1249,10 +1226,10 @@ bool bcache_get(struct bcache *cache, int di, block_address i,
|
||||
*result = b;
|
||||
return true;
|
||||
}
|
||||
bad:
|
||||
|
||||
*result = NULL;
|
||||
|
||||
log_error("bcache failed to get block %u di %d", (uint32_t) i, di);
|
||||
log_error("bcache failed to get block %u fd %d", (uint32_t) i, fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1316,7 +1293,7 @@ static bool _invalidate_block(struct bcache *cache, struct block *b)
|
||||
|
||||
if (b->ref_count) {
|
||||
log_warn("bcache_invalidate: block (%d, %llu) still held",
|
||||
b->di, (unsigned long long) b->index);
|
||||
b->fd, (unsigned long long) b->index);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1333,9 +1310,9 @@ static bool _invalidate_block(struct bcache *cache, struct block *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bcache_invalidate(struct bcache *cache, int di, block_address i)
|
||||
bool bcache_invalidate(struct bcache *cache, int fd, block_address i)
|
||||
{
|
||||
return _invalidate_block(cache, _block_lookup(cache, di, i));
|
||||
return _invalidate_block(cache, _block_lookup(cache, fd, i));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
@@ -1351,27 +1328,27 @@ static bool _writeback_v(struct radix_tree_iterator *it,
|
||||
struct block *b = v.ptr;
|
||||
|
||||
if (_test_flags(b, BF_DIRTY))
|
||||
_issue_write(b);
|
||||
_issue_write(b);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _invalidate_v(struct radix_tree_iterator *it,
|
||||
uint8_t *kb, uint8_t *ke, union radix_value v)
|
||||
{
|
||||
struct block *b = v.ptr;
|
||||
struct invalidate_iterator *iit = container_of(it, struct invalidate_iterator, it);
|
||||
struct invalidate_iterator *iit = container_of(it, struct invalidate_iterator, it);
|
||||
|
||||
if (b->error || _test_flags(b, BF_DIRTY)) {
|
||||
log_warn("WARNING: bcache_invalidate: block (%d, %llu) still dirty.",
|
||||
b->di, (unsigned long long) b->index);
|
||||
iit->success = false;
|
||||
return true;
|
||||
log_warn("bcache_invalidate: block (%d, %llu) still dirty",
|
||||
b->fd, (unsigned long long) b->index);
|
||||
iit->success = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (b->ref_count) {
|
||||
log_warn("WARNING: bcache_invalidate: block (%d, %llu) still held.",
|
||||
b->di, (unsigned long long) b->index);
|
||||
log_warn("bcache_invalidate: block (%d, %llu) still held",
|
||||
b->fd, (unsigned long long) b->index);
|
||||
iit->success = false;
|
||||
return true;
|
||||
}
|
||||
@@ -1384,24 +1361,24 @@ static bool _invalidate_v(struct radix_tree_iterator *it,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bcache_invalidate_di(struct bcache *cache, int di)
|
||||
bool bcache_invalidate_fd(struct bcache *cache, int fd)
|
||||
{
|
||||
union key k;
|
||||
union key k;
|
||||
struct invalidate_iterator it;
|
||||
|
||||
k.parts.di = di;
|
||||
k.parts.fd = fd;
|
||||
|
||||
it.it.visit = _writeback_v;
|
||||
radix_tree_iterate(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di), &it.it);
|
||||
radix_tree_iterate(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.fd), &it.it);
|
||||
|
||||
_wait_all(cache);
|
||||
|
||||
it.success = true;
|
||||
it.it.visit = _invalidate_v;
|
||||
radix_tree_iterate(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di), &it.it);
|
||||
radix_tree_iterate(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.fd), &it.it);
|
||||
|
||||
if (it.success)
|
||||
(void) radix_tree_remove_prefix(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di));
|
||||
radix_tree_remove_prefix(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.fd));
|
||||
|
||||
return it.success;
|
||||
}
|
||||
@@ -1415,7 +1392,7 @@ static bool _abort_v(struct radix_tree_iterator *it,
|
||||
|
||||
if (b->ref_count) {
|
||||
log_fatal("bcache_abort: block (%d, %llu) still held",
|
||||
b->di, (unsigned long long) b->index);
|
||||
b->fd, (unsigned long long) b->index);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1427,94 +1404,35 @@ static bool _abort_v(struct radix_tree_iterator *it,
|
||||
return true;
|
||||
}
|
||||
|
||||
void bcache_abort_di(struct bcache *cache, int di)
|
||||
void bcache_abort_fd(struct bcache *cache, int fd)
|
||||
{
|
||||
union key k;
|
||||
union key k;
|
||||
struct radix_tree_iterator it;
|
||||
|
||||
k.parts.di = di;
|
||||
k.parts.fd = fd;
|
||||
|
||||
it.visit = _abort_v;
|
||||
radix_tree_iterate(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di), &it);
|
||||
(void) radix_tree_remove_prefix(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di));
|
||||
radix_tree_iterate(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.fd), &it);
|
||||
radix_tree_remove_prefix(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.fd));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
void bcache_set_last_byte(struct bcache *cache, int di, uint64_t offset, int sector_size)
|
||||
void bcache_set_last_byte(struct bcache *cache, int fd, uint64_t offset, int sector_size)
|
||||
{
|
||||
_last_byte_di = di;
|
||||
_last_byte_fd = fd;
|
||||
_last_byte_offset = offset;
|
||||
_last_byte_sector_size = sector_size;
|
||||
if (!sector_size)
|
||||
_last_byte_sector_size = 512;
|
||||
}
|
||||
|
||||
void bcache_unset_last_byte(struct bcache *cache, int di)
|
||||
void bcache_unset_last_byte(struct bcache *cache, int fd)
|
||||
{
|
||||
if (_last_byte_di == di) {
|
||||
_last_byte_di = 0;
|
||||
if (_last_byte_fd == fd) {
|
||||
_last_byte_fd = 0;
|
||||
_last_byte_offset = 0;
|
||||
_last_byte_sector_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int bcache_set_fd(int fd)
|
||||
{
|
||||
int *new_table = NULL;
|
||||
int new_size = 0;
|
||||
int i;
|
||||
|
||||
retry:
|
||||
for (i = 0; i < _fd_table_size; i++) {
|
||||
if (_fd_table[i] == -1) {
|
||||
_fd_table[i] = fd;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/* already tried once, shouldn't happen */
|
||||
if (new_size)
|
||||
return -1;
|
||||
|
||||
new_size = _fd_table_size + FD_TABLE_INC;
|
||||
|
||||
new_table = realloc(_fd_table, sizeof(int) * new_size);
|
||||
if (!new_table) {
|
||||
log_error("Cannot extend bcache fd table");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = _fd_table_size; i < new_size; i++)
|
||||
new_table[i] = -1;
|
||||
|
||||
_fd_table = new_table;
|
||||
_fd_table_size = new_size;
|
||||
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/*
|
||||
* Should we check for unflushed or inprogress io on an fd
|
||||
* prior to doing clear_fd or change_fd? (To catch mistakes;
|
||||
* the caller should be smart enough to not do that.)
|
||||
*/
|
||||
|
||||
void bcache_clear_fd(int di)
|
||||
{
|
||||
if (di >= _fd_table_size)
|
||||
return;
|
||||
_fd_table[di] = -1;
|
||||
}
|
||||
|
||||
int bcache_change_fd(int di, int fd)
|
||||
{
|
||||
if (di >= _fd_table_size)
|
||||
return 0;
|
||||
if (di < 0) {
|
||||
log_error(INTERNAL_ERROR "Cannot change not opened DI with FD:%d", fd);
|
||||
return 0;
|
||||
}
|
||||
_fd_table[di] = fd;
|
||||
return 1;
|
||||
}
|
||||
|
@@ -16,12 +16,19 @@
|
||||
#define BCACHE_H
|
||||
|
||||
#include "device_mapper/all.h"
|
||||
#include "base/memory/container_of.h"
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
// FIXME: move somewhere more sensible
|
||||
#define container_of(v, t, head) \
|
||||
((t *)((const char *)(v) - (const char *)&((t *) 0)->head))
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
enum dir {
|
||||
DIR_READ,
|
||||
DIR_WRITE
|
||||
@@ -34,7 +41,7 @@ typedef void io_complete_fn(void *context, int io_error);
|
||||
|
||||
struct io_engine {
|
||||
void (*destroy)(struct io_engine *e);
|
||||
bool (*issue)(struct io_engine *e, enum dir d, int di,
|
||||
bool (*issue)(struct io_engine *e, enum dir d, int fd,
|
||||
sector_t sb, sector_t se, void *data, void *context);
|
||||
bool (*wait)(struct io_engine *e, io_complete_fn fn);
|
||||
unsigned (*max_io)(struct io_engine *e);
|
||||
@@ -48,7 +55,7 @@ struct io_engine *create_sync_io_engine(void);
|
||||
struct bcache;
|
||||
struct block {
|
||||
/* clients may only access these three fields */
|
||||
int di;
|
||||
int fd;
|
||||
uint64_t index;
|
||||
void *data;
|
||||
|
||||
@@ -106,12 +113,12 @@ unsigned bcache_max_prefetches(struct bcache *cache);
|
||||
* they complete. But we're talking a very small difference, and it's worth it
|
||||
* to keep callbacks out of this interface.
|
||||
*/
|
||||
void bcache_prefetch(struct bcache *cache, int di, block_address index);
|
||||
void bcache_prefetch(struct bcache *cache, int fd, block_address index);
|
||||
|
||||
/*
|
||||
* Returns true on success.
|
||||
*/
|
||||
bool bcache_get(struct bcache *cache, int di, block_address index,
|
||||
bool bcache_get(struct bcache *cache, int fd, block_address index,
|
||||
unsigned flags, struct block **result);
|
||||
void bcache_put(struct block *b);
|
||||
|
||||
@@ -129,42 +136,37 @@ bool bcache_flush(struct bcache *cache);
|
||||
*
|
||||
* If the block is currently held false will be returned.
|
||||
*/
|
||||
bool bcache_invalidate(struct bcache *cache, int di, block_address index);
|
||||
bool bcache_invalidate(struct bcache *cache, int fd, block_address index);
|
||||
|
||||
/*
|
||||
* Invalidates all blocks on the given descriptor. Call this before closing
|
||||
* the descriptor to make sure everything is written back.
|
||||
*/
|
||||
bool bcache_invalidate_di(struct bcache *cache, int di);
|
||||
bool bcache_invalidate_fd(struct bcache *cache, int fd);
|
||||
|
||||
/*
|
||||
* Call this function if flush, or invalidate fail and you do not
|
||||
* wish to retry the writes. This will throw away any dirty data
|
||||
* not written. If any blocks for di are held, then it will call
|
||||
* not written. If any blocks for fd are held, then it will call
|
||||
* abort().
|
||||
*/
|
||||
void bcache_abort_di(struct bcache *cache, int di);
|
||||
void bcache_abort_fd(struct bcache *cache, int fd);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// The next four functions are utilities written in terms of the above api.
|
||||
|
||||
// Prefetches the blocks neccessary to satisfy a byte range.
|
||||
void bcache_prefetch_bytes(struct bcache *cache, int di, uint64_t start, size_t len);
|
||||
void bcache_prefetch_bytes(struct bcache *cache, int fd, uint64_t start, size_t len);
|
||||
|
||||
// Reads, writes and zeroes bytes. Returns false if errors occur.
|
||||
bool bcache_read_bytes(struct bcache *cache, int di, uint64_t start, size_t len, void *data);
|
||||
bool bcache_write_bytes(struct bcache *cache, int di, uint64_t start, size_t len, void *data);
|
||||
bool bcache_zero_bytes(struct bcache *cache, int di, uint64_t start, size_t len);
|
||||
bool bcache_set_bytes(struct bcache *cache, int di, uint64_t start, size_t len, uint8_t val);
|
||||
bool bcache_invalidate_bytes(struct bcache *cache, int di, uint64_t start, size_t len);
|
||||
bool bcache_read_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, void *data);
|
||||
bool bcache_write_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, void *data);
|
||||
bool bcache_zero_bytes(struct bcache *cache, int fd, uint64_t start, size_t len);
|
||||
bool bcache_set_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, uint8_t val);
|
||||
|
||||
void bcache_set_last_byte(struct bcache *cache, int di, uint64_t offset, int sector_size);
|
||||
void bcache_unset_last_byte(struct bcache *cache, int di);
|
||||
void bcache_set_last_byte(struct bcache *cache, int fd, uint64_t offset, int sector_size);
|
||||
void bcache_unset_last_byte(struct bcache *cache, int fd);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
int bcache_set_fd(int fd); /* returns di */
|
||||
void bcache_clear_fd(int di);
|
||||
int bcache_change_fd(int di, int fd);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -28,12 +28,13 @@ struct cmd_context;
|
||||
struct dev_filter {
|
||||
int (*passes_filter) (struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name);
|
||||
void (*destroy) (struct dev_filter *f);
|
||||
void (*wipe) (struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name);
|
||||
void (*wipe) (struct dev_filter *f);
|
||||
void *private;
|
||||
unsigned use_count;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
int dev_cache_index_devs(void);
|
||||
struct dm_list *dev_cache_get_dev_list_for_vgid(const char *vgid);
|
||||
struct dm_list *dev_cache_get_dev_list_for_lvid(const char *lvid);
|
||||
|
||||
@@ -53,11 +54,10 @@ int dev_cache_has_scanned(void);
|
||||
|
||||
int dev_cache_add_dir(const char *path);
|
||||
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f);
|
||||
const char *dev_cache_filtered_reason(const char *name);
|
||||
|
||||
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t device, struct dev_filter *f, int *filtered);
|
||||
|
||||
struct device *dev_hash_get(const char *name);
|
||||
|
||||
void dev_set_preferred_name(struct dm_str_list *sl, struct device *dev);
|
||||
|
||||
/*
|
||||
@@ -74,10 +74,4 @@ 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 setup_devices_file(struct cmd_context *cmd);
|
||||
int setup_devices(struct cmd_context *cmd);
|
||||
int setup_device(struct cmd_context *cmd, const char *devname);
|
||||
|
||||
#endif
|
||||
|
@@ -81,7 +81,7 @@ typedef struct dasd_information2_t {
|
||||
int dasd_is_cdl_formatted(struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
dasd_information2_t dasd_info2 = { 0 };
|
||||
dasd_information2_t dasd_info2;
|
||||
|
||||
if (!dev_open_readonly(dev))
|
||||
return_0;
|
||||
|
@@ -86,9 +86,6 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
|
||||
int fd = dev->bcache_fd;
|
||||
int do_close = 0;
|
||||
|
||||
if (dm_list_empty(&dev->aliases))
|
||||
return 0;
|
||||
|
||||
if (dev->size_seqno == _dev_size_seqno) {
|
||||
log_very_verbose("%s: using cached size %" PRIu64 " sectors",
|
||||
name, dev->size);
|
||||
@@ -97,16 +94,16 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
|
||||
}
|
||||
|
||||
if (fd <= 0) {
|
||||
if (!dev_open_readonly_quiet(dev))
|
||||
if (!dev_open_readonly(dev))
|
||||
return_0;
|
||||
fd = dev_fd(dev);
|
||||
do_close = 1;
|
||||
}
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE64, size) < 0) {
|
||||
log_warn("WARNING: %s: ioctl BLKGETSIZE64 %s", name, strerror(errno));
|
||||
log_sys_error("ioctl BLKGETSIZE64", name);
|
||||
if (do_close && !dev_close_immediate(dev))
|
||||
stack;
|
||||
log_sys_error("close", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -117,28 +114,25 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
|
||||
log_very_verbose("%s: size is %" PRIu64 " sectors", name, *size);
|
||||
|
||||
if (do_close && !dev_close_immediate(dev))
|
||||
stack;
|
||||
log_sys_error("close", name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _dev_read_ahead_dev(struct device *dev, uint32_t *read_ahead)
|
||||
{
|
||||
long read_ahead_long = 0;
|
||||
long read_ahead_long;
|
||||
|
||||
if (dev->read_ahead != -1) {
|
||||
*read_ahead = (uint32_t) dev->read_ahead;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!dev_open_readonly_quiet(dev)) {
|
||||
log_warn("WARNING: Failed to open %s to get readahead %s.",
|
||||
dev_name(dev), strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (!dev_open_readonly(dev))
|
||||
return_0;
|
||||
|
||||
if (ioctl(dev->fd, BLKRAGET, &read_ahead_long) < 0) {
|
||||
log_warn("WARNING: %s: ioctl BLKRAGET %s.", dev_name(dev), strerror(errno));
|
||||
log_sys_error("ioctl BLKRAGET", dev_name(dev));
|
||||
if (!dev_close_immediate(dev))
|
||||
stack;
|
||||
return 0;
|
||||
@@ -171,7 +165,7 @@ static int _dev_discard_blocks(struct device *dev, uint64_t offset_bytes, uint64
|
||||
test_mode() ? " (test mode - suppressed)" : "");
|
||||
|
||||
if (!test_mode() && ioctl(dev->fd, BLKDISCARD, &discard_range) < 0) {
|
||||
log_warn("WARNING: %s: ioctl BLKDISCARD at offset %" PRIu64 " size %" PRIu64 " failed: %s.",
|
||||
log_error("%s: BLKDISCARD ioctl at offset %" PRIu64 " size %" PRIu64 " failed: %s.",
|
||||
dev_name(dev), offset_bytes, size_bytes, strerror(errno));
|
||||
if (!dev_close_immediate(dev))
|
||||
stack;
|
||||
@@ -200,7 +194,7 @@ int dev_get_direct_block_sizes(struct device *dev, unsigned int *physical_block_
|
||||
}
|
||||
|
||||
if (fd <= 0) {
|
||||
if (!dev_open_readonly_quiet(dev))
|
||||
if (!dev_open_readonly(dev))
|
||||
return 0;
|
||||
fd = dev_fd(dev);
|
||||
do_close = 1;
|
||||
@@ -450,7 +444,7 @@ int dev_open_readonly_quiet(struct device *dev)
|
||||
static void _close(struct device *dev)
|
||||
{
|
||||
if (close(dev->fd))
|
||||
log_sys_debug("close", dev_name(dev));
|
||||
log_sys_error("close", dev_name(dev));
|
||||
dev->fd = -1;
|
||||
|
||||
log_debug_devs("Closed %s", dev_name(dev));
|
||||
|
@@ -16,7 +16,6 @@
|
||||
#include "lib/misc/lib.h"
|
||||
#include "lib/device/dev-type.h"
|
||||
#include "lib/mm/xlate.h"
|
||||
#include "lib/misc/crc.h"
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
#include <libudev.h> /* for MD detection using udev db records */
|
||||
#include "lib/device/dev-ext-udev-constants.h"
|
||||
@@ -49,99 +48,44 @@ static int _dev_has_md_magic(struct device *dev, uint64_t sb_offset)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define IMSM_SIGNATURE "Intel Raid ISM Cfg Sig. "
|
||||
#define IMSM_SIG_LEN (sizeof(IMSM_SIGNATURE) - 1)
|
||||
/*
|
||||
* Calculate the position of the superblock.
|
||||
* It is always aligned to a 4K boundary and
|
||||
* depending on minor_version, it can be:
|
||||
* 0: At least 8K, but less than 12K, from end of device
|
||||
* 1: At start of device
|
||||
* 2: 4K from start of device.
|
||||
*/
|
||||
typedef enum {
|
||||
MD_MINOR_VERSION_MIN,
|
||||
MD_MINOR_V0 = MD_MINOR_VERSION_MIN,
|
||||
MD_MINOR_V1,
|
||||
MD_MINOR_V2,
|
||||
MD_MINOR_VERSION_MAX = MD_MINOR_V2
|
||||
} md_minor_version_t;
|
||||
|
||||
static int _dev_has_imsm_magic(struct device *dev, uint64_t devsize_sectors)
|
||||
static uint64_t _v1_sb_offset(uint64_t size, md_minor_version_t minor_version)
|
||||
{
|
||||
char imsm_signature[IMSM_SIG_LEN];
|
||||
uint64_t off = (devsize_sectors * 512) - 1024;
|
||||
unsigned int physical_block_size = 0;
|
||||
unsigned int logical_block_size = 0;
|
||||
uint64_t sb_offset;
|
||||
|
||||
if (!dev_get_direct_block_sizes(dev, &physical_block_size, &logical_block_size))
|
||||
return_0;
|
||||
|
||||
if (logical_block_size == 4096)
|
||||
off = (devsize_sectors * 512) - 8192;
|
||||
else
|
||||
off = (devsize_sectors * 512) - 1024;
|
||||
|
||||
if (!dev_read_bytes(dev, off, IMSM_SIG_LEN, imsm_signature))
|
||||
return_0;
|
||||
|
||||
if (!memcmp(imsm_signature, IMSM_SIGNATURE, IMSM_SIG_LEN))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DDF_MAGIC 0xDE11DE11
|
||||
struct ddf_header {
|
||||
uint32_t magic;
|
||||
uint32_t crc;
|
||||
char guid[24];
|
||||
char revision[8];
|
||||
char padding[472];
|
||||
};
|
||||
|
||||
static int _dev_has_ddf_magic(struct device *dev, uint64_t devsize_sectors, uint64_t *sb_offset)
|
||||
{
|
||||
struct ddf_header hdr;
|
||||
uint32_t crc, our_crc;
|
||||
uint64_t off;
|
||||
uint64_t devsize_bytes = devsize_sectors * 512;
|
||||
|
||||
if (devsize_bytes < 0x30000)
|
||||
switch(minor_version) {
|
||||
case MD_MINOR_V0:
|
||||
sb_offset = (size - 8 * 2) & ~(4 * 2 - 1ULL);
|
||||
break;
|
||||
case MD_MINOR_V1:
|
||||
sb_offset = 0;
|
||||
break;
|
||||
case MD_MINOR_V2:
|
||||
sb_offset = 4 * 2;
|
||||
break;
|
||||
default:
|
||||
log_warn(INTERNAL_ERROR "WARNING: Unknown minor version %d.",
|
||||
minor_version);
|
||||
return 0;
|
||||
|
||||
/* 512 bytes before the end of device (from libblkid) */
|
||||
off = ((devsize_bytes / 0x200) - 1) * 0x200;
|
||||
|
||||
if (!dev_read_bytes(dev, off, 512, &hdr))
|
||||
return_0;
|
||||
|
||||
if ((hdr.magic == cpu_to_be32(DDF_MAGIC)) ||
|
||||
(hdr.magic == cpu_to_le32(DDF_MAGIC))) {
|
||||
crc = hdr.crc;
|
||||
hdr.crc = 0xffffffff;
|
||||
our_crc = calc_crc(0, (const uint8_t *)&hdr, 512);
|
||||
|
||||
if ((cpu_to_be32(our_crc) == crc) ||
|
||||
(cpu_to_le32(our_crc) == crc)) {
|
||||
*sb_offset = off;
|
||||
return 1;
|
||||
} else {
|
||||
log_debug_devs("Found md ddf magic at %llu wrong crc %x disk %x %s",
|
||||
(unsigned long long)off, our_crc, crc, dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sb_offset <<= SECTOR_SHIFT;
|
||||
|
||||
/* 128KB before the end of device (from libblkid) */
|
||||
off = ((devsize_bytes / 0x200) - 257) * 0x200;
|
||||
|
||||
if (!dev_read_bytes(dev, off, 512, &hdr))
|
||||
return_0;
|
||||
|
||||
if ((hdr.magic == cpu_to_be32(DDF_MAGIC)) ||
|
||||
(hdr.magic == cpu_to_le32(DDF_MAGIC))) {
|
||||
crc = hdr.crc;
|
||||
hdr.crc = 0xffffffff;
|
||||
our_crc = calc_crc(0, (const uint8_t *)&hdr, 512);
|
||||
|
||||
if ((cpu_to_be32(our_crc) == crc) ||
|
||||
(cpu_to_le32(our_crc) == crc)) {
|
||||
*sb_offset = off;
|
||||
return 1;
|
||||
} else {
|
||||
log_debug_devs("Found md ddf magic at %llu wrong crc %x disk %x %s",
|
||||
(unsigned long long)off, our_crc, crc, dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return sb_offset;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -166,14 +110,17 @@ static int _udev_dev_is_md_component(struct device *dev)
|
||||
if (!(ext = dev_ext_get(dev)))
|
||||
return_0;
|
||||
|
||||
if (!(value = udev_device_get_property_value((struct udev_device *)ext->handle, DEV_EXT_UDEV_BLKID_TYPE)))
|
||||
if (!(value = udev_device_get_property_value((struct udev_device *)ext->handle, DEV_EXT_UDEV_BLKID_TYPE))) {
|
||||
dev->flags |= DEV_UDEV_INFO_MISSING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return !strcmp(value, DEV_EXT_UDEV_BLKID_TYPE_SW_RAID);
|
||||
}
|
||||
#else
|
||||
static int _udev_dev_is_md_component(struct device *dev)
|
||||
{
|
||||
dev->flags |= DEV_UDEV_INFO_MISSING;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -183,7 +130,8 @@ static int _udev_dev_is_md_component(struct device *dev)
|
||||
*/
|
||||
static int _native_dev_is_md_component(struct device *dev, uint64_t *offset_found, int full)
|
||||
{
|
||||
uint64_t size, sb_offset = 0;
|
||||
md_minor_version_t minor;
|
||||
uint64_t size, sb_offset;
|
||||
int ret;
|
||||
|
||||
if (!scan_bcache)
|
||||
@@ -198,9 +146,9 @@ static int _native_dev_is_md_component(struct device *dev, uint64_t *offset_foun
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Some md versions locate the magic number at the end of the device.
|
||||
* Those checks can't be satisfied with the initial scan data, and
|
||||
* require an extra read i/o at the end of every device. Issuing
|
||||
* Old md versions locate the magic number at the end of the device.
|
||||
* Those checks can't be satisfied with the initial bcache data, and
|
||||
* would require an extra read i/o at the end of every device. Issuing
|
||||
* an extra read to every device in every command, just to check for
|
||||
* the old md format is a bad tradeoff.
|
||||
*
|
||||
@@ -211,81 +159,42 @@ static int _native_dev_is_md_component(struct device *dev, uint64_t *offset_foun
|
||||
* and set it for commands that could possibly write to an md dev
|
||||
* (pvcreate/vgcreate/vgextend).
|
||||
*/
|
||||
|
||||
/*
|
||||
* md superblock version 1.1 at offset 0 from start
|
||||
*/
|
||||
|
||||
if (_dev_has_md_magic(dev, 0)) {
|
||||
log_debug_devs("Found md magic number at offset 0 of %s.", dev_name(dev));
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* md superblock version 1.2 at offset 4KB from start
|
||||
*/
|
||||
|
||||
if (_dev_has_md_magic(dev, 4096)) {
|
||||
log_debug_devs("Found md magic number at offset 4096 of %s.", dev_name(dev));
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!full) {
|
||||
sb_offset = 0;
|
||||
if (_dev_has_md_magic(dev, sb_offset)) {
|
||||
log_debug_devs("Found md magic number at offset 0 of %s.", dev_name(dev));
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sb_offset = 8 << SECTOR_SHIFT;
|
||||
if (_dev_has_md_magic(dev, sb_offset)) {
|
||||
log_debug_devs("Found md magic number at offset %d of %s.", (int)sb_offset, dev_name(dev));
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle superblocks at the end of the device.
|
||||
*/
|
||||
|
||||
/*
|
||||
* md superblock version 0 at 64KB from end of device
|
||||
* (after end is aligned to 64KB)
|
||||
*/
|
||||
|
||||
/* Check if it is an md component device. */
|
||||
/* Version 0.90.0 */
|
||||
sb_offset = MD_NEW_SIZE_SECTORS(size) << SECTOR_SHIFT;
|
||||
|
||||
if (_dev_has_md_magic(dev, sb_offset)) {
|
||||
log_debug_devs("Found md magic number at offset %llu of %s.", (unsigned long long)sb_offset, dev_name(dev));
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* md superblock version 1.0 at 8KB from end of device
|
||||
*/
|
||||
|
||||
sb_offset = ((size - 8 * 2) & ~(4 * 2 - 1ULL)) << SECTOR_SHIFT;
|
||||
|
||||
if (_dev_has_md_magic(dev, sb_offset)) {
|
||||
log_debug_devs("Found md magic number at offset %llu of %s.", (unsigned long long)sb_offset, dev_name(dev));
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* md imsm superblock 1K from end of device
|
||||
*/
|
||||
|
||||
if (_dev_has_imsm_magic(dev, size)) {
|
||||
log_debug_devs("Found md imsm magic number at offset %llu of %s.", (unsigned long long)sb_offset, dev_name(dev));
|
||||
sb_offset = 1024;
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* md ddf superblock 512 bytes from end, or 128KB from end
|
||||
*/
|
||||
|
||||
if (_dev_has_ddf_magic(dev, size, &sb_offset)) {
|
||||
log_debug_devs("Found md ddf magic number at offset %llu of %s.", (unsigned long long)sb_offset, dev_name(dev));
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
minor = MD_MINOR_VERSION_MIN;
|
||||
/* Version 1, try v1.0 -> v1.2 */
|
||||
do {
|
||||
sb_offset = _v1_sb_offset(size, minor);
|
||||
if (_dev_has_md_magic(dev, sb_offset)) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
} while (++minor <= MD_MINOR_VERSION_MAX);
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
|
@@ -21,7 +21,6 @@
|
||||
#include "lib/metadata/metadata.h"
|
||||
#include "lib/device/bcache.h"
|
||||
#include "lib/label/label.h"
|
||||
#include "lib/commands/toolcontext.h"
|
||||
|
||||
#ifdef BLKID_WIPING_SUPPORT
|
||||
#include <blkid.h>
|
||||
@@ -36,16 +35,48 @@
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* An nvme device has major number 259 (BLKEXT), minor number <minor>,
|
||||
* and reading /sys/dev/block/259:<minor>/device/dev shows a character
|
||||
* device cmajor:cminor where cmajor matches the major number of the
|
||||
* nvme character device entry in /proc/devices. Checking all of that
|
||||
* is excessive and unnecessary compared to just comparing /dev/name*.
|
||||
* dev is pmem if /sys/dev/block/<major>:<minor>/queue/dax is 1
|
||||
*/
|
||||
|
||||
int dev_is_nvme(struct dev_types *dt, struct device *dev)
|
||||
int dev_is_pmem(struct device *dev)
|
||||
{
|
||||
return (dev->flags & DEV_IS_NVME) ? 1 : 0;
|
||||
FILE *fp;
|
||||
char path[PATH_MAX];
|
||||
char buffer[64];
|
||||
int is_pmem = 0;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/queue/dax",
|
||||
dm_sysfs_dir(),
|
||||
(int) MAJOR(dev->dev),
|
||||
(int) MINOR(dev->dev)) < 0) {
|
||||
log_warn("Sysfs path for %s dax is too long.", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(fp = fopen(path, "r")))
|
||||
return 0;
|
||||
|
||||
if (!fgets(buffer, sizeof(buffer), fp)) {
|
||||
log_warn("Failed to read %s.", path);
|
||||
if (fclose(fp))
|
||||
log_sys_debug("fclose", path);
|
||||
return 0;
|
||||
} else if (sscanf(buffer, "%d", &is_pmem) != 1) {
|
||||
log_warn("Failed to parse %s '%s'.", path, buffer);
|
||||
if (fclose(fp))
|
||||
log_sys_debug("fclose", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fclose(fp))
|
||||
log_sys_debug("fclose", path);
|
||||
|
||||
if (is_pmem) {
|
||||
log_debug("%s is pmem", dev_name(dev));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dev_is_lv(struct device *dev)
|
||||
@@ -53,7 +84,6 @@ int dev_is_lv(struct device *dev)
|
||||
FILE *fp;
|
||||
char path[PATH_MAX];
|
||||
char buffer[64];
|
||||
int ret = 0;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/dm/uuid",
|
||||
dm_sysfs_dir(),
|
||||
@@ -66,15 +96,17 @@ int dev_is_lv(struct device *dev)
|
||||
if (!(fp = fopen(path, "r")))
|
||||
return 0;
|
||||
|
||||
if (!fgets(buffer, sizeof(buffer), fp))
|
||||
log_debug("Failed to read %s.", path);
|
||||
else if (!strncmp(buffer, "LVM-", 4))
|
||||
ret = 1;
|
||||
if (!fgets(buffer, sizeof(buffer), fp)) {
|
||||
log_warn("Failed to read %s.", path);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fclose(fp))
|
||||
log_sys_debug("fclose", path);
|
||||
fclose(fp);
|
||||
|
||||
return ret;
|
||||
if (!strncmp(buffer, "LVM-", 4))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dev_types *create_dev_types(const char *proc_dir,
|
||||
@@ -211,7 +243,7 @@ struct dev_types *create_dev_types(const char *proc_dir,
|
||||
log_error("Expecting string in devices/types "
|
||||
"in config file");
|
||||
if (fclose(pd))
|
||||
log_sys_debug("fclose", proc_devices);
|
||||
log_sys_error("fclose", proc_devices);
|
||||
goto bad;
|
||||
}
|
||||
dev_len = strlen(cv->v.str);
|
||||
@@ -222,7 +254,7 @@ struct dev_types *create_dev_types(const char *proc_dir,
|
||||
"in devices/types in config file",
|
||||
name);
|
||||
if (fclose(pd))
|
||||
log_sys_debug("fclose", proc_devices);
|
||||
log_sys_error("fclose", proc_devices);
|
||||
goto bad;
|
||||
}
|
||||
if (!cv->v.i) {
|
||||
@@ -230,7 +262,7 @@ struct dev_types *create_dev_types(const char *proc_dir,
|
||||
"%s in devices/types in config file",
|
||||
name);
|
||||
if (fclose(pd))
|
||||
log_sys_debug("fclose", proc_devices);
|
||||
log_sys_error("fclose", proc_devices);
|
||||
goto bad;
|
||||
}
|
||||
if (dev_len <= strlen(line + i) &&
|
||||
@@ -283,9 +315,6 @@ int dev_subsystem_part_major(struct dev_types *dt, struct device *dev)
|
||||
|
||||
const char *dev_subsystem_name(struct dev_types *dt, struct device *dev)
|
||||
{
|
||||
if (dev->flags & DEV_IS_NVME)
|
||||
return "NVME";
|
||||
|
||||
if (MAJOR(dev->dev) == dt->device_mapper_major)
|
||||
return "DM";
|
||||
|
||||
@@ -332,6 +361,7 @@ int major_is_scsi_device(struct dev_types *dt, int major)
|
||||
return (dt->dev_type_array[major].flags & PARTITION_SCSI_DEVICE) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
static int _loop_is_with_partscan(struct device *dev)
|
||||
{
|
||||
FILE *fp;
|
||||
@@ -363,45 +393,6 @@ static int _loop_is_with_partscan(struct device *dev)
|
||||
return partscan;
|
||||
}
|
||||
|
||||
int dev_get_partition_number(struct device *dev, int *num)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char buf[8] = { 0 };
|
||||
dev_t devt = dev->dev;
|
||||
struct stat sb;
|
||||
|
||||
if (dev->part != -1) {
|
||||
*num = dev->part;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/partition",
|
||||
dm_sysfs_dir(), (int)MAJOR(devt), (int)MINOR(devt)) < 0) {
|
||||
log_error("Failed to create sysfs path for %s", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (stat(path, &sb)) {
|
||||
dev->part = 0;
|
||||
*num = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!get_sysfs_value(path, buf, sizeof(buf), 0)) {
|
||||
log_error("Failed to read sysfs path for %s", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!buf[0]) {
|
||||
log_error("Failed to read sysfs partition value for %s", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->part = atoi(buf);
|
||||
*num = dev->part;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* See linux/genhd.h and fs/partitions/msdos */
|
||||
#define PART_MAGIC 0xAA55
|
||||
#define PART_MAGIC_OFFSET UINT64_C(0x1FE)
|
||||
@@ -420,28 +411,6 @@ struct partition {
|
||||
uint32_t nr_sects;
|
||||
} __attribute__((packed));
|
||||
|
||||
static int _has_sys_partition(struct device *dev)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
struct stat info;
|
||||
int major = (int) MAJOR(dev->dev);
|
||||
int minor = (int) MINOR(dev->dev);
|
||||
|
||||
/* check if dev is a partition */
|
||||
if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d/partition",
|
||||
dm_sysfs_dir(), major, minor) < 0) {
|
||||
log_warn("WARNING: %s: partition path is too long.", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (stat(path, &info) == -1) {
|
||||
if (errno != ENOENT)
|
||||
log_sys_debug("stat", path);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _is_partitionable(struct dev_types *dt, struct device *dev)
|
||||
{
|
||||
int parts = major_max_partitions(dt, MAJOR(dev->dev));
|
||||
@@ -458,13 +427,6 @@ static int _is_partitionable(struct dev_types *dt, struct device *dev)
|
||||
_loop_is_with_partscan(dev))
|
||||
return 1;
|
||||
|
||||
if (dev_is_nvme(dt, dev)) {
|
||||
/* If this dev is already a partition then it's not partitionable. */
|
||||
if (_has_sys_partition(dev))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((parts <= 1) || (MINOR(dev->dev) % parts))
|
||||
return 0;
|
||||
|
||||
@@ -602,22 +564,16 @@ int dev_is_partitioned(struct dev_types *dt, struct device *dev)
|
||||
*/
|
||||
int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
|
||||
{
|
||||
const char *sysfs_dir = dm_sysfs_dir();
|
||||
int major = (int) MAJOR(dev->dev);
|
||||
int minor = (int) MINOR(dev->dev);
|
||||
char path[PATH_MAX];
|
||||
char temp_path[PATH_MAX];
|
||||
char buffer[64];
|
||||
struct stat info;
|
||||
FILE *fp = NULL;
|
||||
int parts, residue, size, ret = 0;
|
||||
|
||||
/*
|
||||
* /dev/nvme devs don't use the major:minor numbering like
|
||||
* block dev types that have their own major number, so
|
||||
* the calculation based on minor number doesn't work.
|
||||
*/
|
||||
if (dev_is_nvme(dt, dev))
|
||||
goto sys_partition;
|
||||
|
||||
/*
|
||||
* Try to get the primary dev out of the
|
||||
* list of known device types first.
|
||||
@@ -633,14 +589,23 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
|
||||
goto out;
|
||||
}
|
||||
|
||||
sys_partition:
|
||||
/*
|
||||
* If we can't get the primary dev out of the list of known device
|
||||
* types, try to look at sysfs directly then. This is more complex
|
||||
* way and it also requires certain sysfs layout to be present
|
||||
* which might not be there in old kernels!
|
||||
*/
|
||||
if (!_has_sys_partition(dev)) {
|
||||
|
||||
/* check if dev is a partition */
|
||||
if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d/partition",
|
||||
sysfs_dir, major, minor) < 0) {
|
||||
log_error("dm_snprintf partition failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (stat(path, &info) == -1) {
|
||||
if (errno != ENOENT)
|
||||
log_sys_error("stat", path);
|
||||
*result = dev->dev;
|
||||
ret = 1;
|
||||
goto out; /* dev is not a partition! */
|
||||
@@ -653,31 +618,25 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
|
||||
* - basename ../../block/md0/md0 = md0
|
||||
* Parent's 'dev' sysfs attribute = /sys/block/md0/dev
|
||||
*/
|
||||
if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d",
|
||||
dm_sysfs_dir(), major, minor) < 0) {
|
||||
log_warn("WARNING: %s: major:minor sysfs path is too long.", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
if ((size = readlink(path, temp_path, sizeof(temp_path) - 1)) < 0) {
|
||||
log_warn("WARNING: Readlink of %s failed.", path);
|
||||
if ((size = readlink(dirname(path), temp_path, sizeof(temp_path) - 1)) < 0) {
|
||||
log_sys_error("readlink", path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
temp_path[size] = '\0';
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%s/block/%s/dev",
|
||||
dm_sysfs_dir(), basename(dirname(temp_path))) < 0) {
|
||||
log_warn("WARNING: sysfs path for %s is too long.",
|
||||
basename(dirname(temp_path)));
|
||||
sysfs_dir, basename(dirname(temp_path))) < 0) {
|
||||
log_error("dm_snprintf dev failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* finally, parse 'dev' attribute and create corresponding dev_t */
|
||||
if (!(fp = fopen(path, "r"))) {
|
||||
if (errno == ENOENT)
|
||||
log_debug("sysfs file %s does not exist.", path);
|
||||
log_error("sysfs file %s does not exist.", path);
|
||||
else
|
||||
log_sys_debug("fopen", path);
|
||||
log_sys_error("fopen", path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -687,7 +646,7 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
|
||||
}
|
||||
|
||||
if (sscanf(buffer, "%d:%d", &major, &minor) != 2) {
|
||||
log_warn("WARNING: sysfs file %s not in expected MAJ:MIN format: %s",
|
||||
log_error("sysfs file %s not in expected MAJ:MIN format: %s",
|
||||
path, buffer);
|
||||
goto out;
|
||||
}
|
||||
@@ -695,36 +654,11 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
|
||||
ret = 2;
|
||||
out:
|
||||
if (fp && fclose(fp))
|
||||
log_sys_debug("fclose", path);
|
||||
log_sys_error("fclose", path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef BLKID_WIPING_SUPPORT
|
||||
int get_fs_block_size(struct device *dev, uint32_t *fs_block_size)
|
||||
{
|
||||
char *block_size_str = NULL;
|
||||
|
||||
if ((block_size_str = blkid_get_tag_value(NULL, "BLOCK_SIZE", dev_name(dev)))) {
|
||||
*fs_block_size = (uint32_t)atoi(block_size_str);
|
||||
free(block_size_str);
|
||||
log_debug("Found blkid BLOCK_SIZE %u for fs on %s", *fs_block_size, dev_name(dev));
|
||||
return 1;
|
||||
} else {
|
||||
log_debug("No blkid BLOCK_SIZE for fs on %s", dev_name(dev));
|
||||
*fs_block_size = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
int get_fs_block_size(struct device *dev, uint32_t *fs_block_size)
|
||||
{
|
||||
log_debug("Disabled blkid BLOCK_SIZE for fs.");
|
||||
*fs_block_size = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BLKID_WIPING_SUPPORT
|
||||
|
||||
static inline int _type_in_flag_list(const char *type, uint32_t flag_list)
|
||||
@@ -757,7 +691,7 @@ static int _blkid_wipe(blkid_probe probe, struct device *dev, const char *name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_warn("WARNING: " MSG_FAILED_SIG_OFFSET MSG_WIPING_SKIPPED, type, name);
|
||||
log_error("WARNING: " MSG_FAILED_SIG_OFFSET MSG_WIPING_SKIPPED, type, name);
|
||||
return 2;
|
||||
}
|
||||
if (blkid_probe_lookup_value(probe, "SBMAGIC", &magic, &len)) {
|
||||
@@ -891,7 +825,7 @@ static int _wipe_signature(struct device *dev, const char *type, const char *nam
|
||||
int (*signature_detection_fn)(struct device *dev, uint64_t *offset_found, int full))
|
||||
{
|
||||
int wipe;
|
||||
uint64_t offset_found = 0;
|
||||
uint64_t offset_found;
|
||||
|
||||
wipe = signature_detection_fn(dev, &offset_found, 1);
|
||||
if (wipe == -1) {
|
||||
@@ -955,9 +889,9 @@ int wipe_known_signatures(struct cmd_context *cmd, struct device *dev,
|
||||
yes, force, wiped);
|
||||
#endif
|
||||
if (blkid_wiping_enabled) {
|
||||
log_warn("WARNING: allocation/use_blkid_wiping=1 configuration setting is set "
|
||||
log_warn("allocation/use_blkid_wiping=1 configuration setting is set "
|
||||
"while LVM is not compiled with blkid wiping support.");
|
||||
log_warn("WARNING: Falling back to native LVM signature detection.");
|
||||
log_warn("Falling back to native LVM signature detection.");
|
||||
}
|
||||
return _wipe_known_signatures_with_lvm(dev, name,
|
||||
types_to_exclude,
|
||||
@@ -973,23 +907,25 @@ static int _snprintf_attr(char *buf, size_t buf_size, const char *sysfs_dir,
|
||||
if (dm_snprintf(buf, buf_size, "%s/dev/block/%d:%d/%s", sysfs_dir,
|
||||
(int)MAJOR(dev), (int)MINOR(dev),
|
||||
attribute) < 0) {
|
||||
log_warn("WARNING: sysfs path for %s attribute is too long.", attribute);
|
||||
log_warn("dm_snprintf %s failed.", attribute);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _dev_sysfs_block_attribute(struct dev_types *dt,
|
||||
const char *attribute,
|
||||
struct device *dev,
|
||||
unsigned long *value)
|
||||
static unsigned long _dev_topology_attribute(struct dev_types *dt,
|
||||
const char *attribute,
|
||||
struct device *dev,
|
||||
unsigned long default_value)
|
||||
{
|
||||
const char *sysfs_dir = dm_sysfs_dir();
|
||||
char path[PATH_MAX], buffer[64];
|
||||
FILE *fp;
|
||||
dev_t primary = 0;
|
||||
int ret = 0;
|
||||
struct stat info;
|
||||
dev_t uninitialized_var(primary);
|
||||
unsigned long result = default_value;
|
||||
unsigned long value = 0UL;
|
||||
|
||||
if (!attribute || !*attribute)
|
||||
goto_out;
|
||||
@@ -998,16 +934,16 @@ static int _dev_sysfs_block_attribute(struct dev_types *dt,
|
||||
goto_out;
|
||||
|
||||
if (!_snprintf_attr(path, sizeof(path), sysfs_dir, attribute, dev->dev))
|
||||
goto_out;
|
||||
goto_out;
|
||||
|
||||
/*
|
||||
* check if the desired sysfs attribute exists
|
||||
* - if not: either the kernel doesn't have topology support
|
||||
* or the device could be a partition
|
||||
*/
|
||||
if (!(fp = fopen(path, "r"))) {
|
||||
if (stat(path, &info) == -1) {
|
||||
if (errno != ENOENT) {
|
||||
log_sys_debug("fopen", path);
|
||||
log_sys_debug("stat", path);
|
||||
goto out;
|
||||
}
|
||||
if (!dev_get_primary_dev(dt, dev, &primary))
|
||||
@@ -1017,54 +953,44 @@ static int _dev_sysfs_block_attribute(struct dev_types *dt,
|
||||
if (!_snprintf_attr(path, sizeof(path), sysfs_dir, attribute, primary))
|
||||
goto_out;
|
||||
|
||||
if (!(fp = fopen(path, "r"))) {
|
||||
if (stat(path, &info) == -1) {
|
||||
if (errno != ENOENT)
|
||||
log_sys_debug("fopen", path);
|
||||
log_sys_debug("stat", path);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(fp = fopen(path, "r"))) {
|
||||
log_sys_debug("fopen", path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!fgets(buffer, sizeof(buffer), fp)) {
|
||||
log_sys_debug("fgets", path);
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
if (sscanf(buffer, "%lu", value) != 1) {
|
||||
log_warn("WARNING: sysfs file %s not in expected format: %s", path, buffer);
|
||||
if (sscanf(buffer, "%lu", &value) != 1) {
|
||||
log_warn("sysfs file %s not in expected format: %s", path, buffer);
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
log_very_verbose("Device %s: %s is %lu%s.",
|
||||
dev_name(dev), attribute, value, default_value ? "" : " bytes");
|
||||
|
||||
result = value >> SECTOR_SHIFT;
|
||||
|
||||
if (!result && value) {
|
||||
log_warn("WARNING: Device %s: %s is %lu and is unexpectedly less than sector.",
|
||||
dev_name(dev), attribute, value);
|
||||
result = 1;
|
||||
}
|
||||
|
||||
out_close:
|
||||
if (fclose(fp))
|
||||
log_sys_debug("fclose", path);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned long _dev_topology_attribute(struct dev_types *dt,
|
||||
const char *attribute,
|
||||
struct device *dev,
|
||||
unsigned long default_value)
|
||||
{
|
||||
unsigned long result = default_value;
|
||||
unsigned long value = 0UL;
|
||||
|
||||
if (_dev_sysfs_block_attribute(dt, attribute, dev, &value)) {
|
||||
log_very_verbose("Device %s: %s is %lu%s.",
|
||||
dev_name(dev), attribute, value, default_value ? "" : " bytes");
|
||||
|
||||
result = value >> SECTOR_SHIFT;
|
||||
|
||||
if (!result && value) {
|
||||
log_warn("WARNING: Device %s: %s is %lu and is unexpectedly less than sector.",
|
||||
dev_name(dev), attribute, value);
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1095,17 +1021,8 @@ unsigned long dev_discard_granularity(struct dev_types *dt, struct device *dev)
|
||||
|
||||
int dev_is_rotational(struct dev_types *dt, struct device *dev)
|
||||
{
|
||||
unsigned long value;
|
||||
return _dev_sysfs_block_attribute(dt, "queue/rotational", dev, &value) ? (int) value : 1;
|
||||
return (int) _dev_topology_attribute(dt, "queue/rotational", dev, 1UL);
|
||||
}
|
||||
|
||||
/* dev is pmem if /sys/dev/block/<major>:<minor>/queue/dax is 1 */
|
||||
int dev_is_pmem(struct dev_types *dt, struct device *dev)
|
||||
{
|
||||
unsigned long value;
|
||||
return _dev_sysfs_block_attribute(dt, "queue/dax", dev, &value) ? (int) value : 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
|
||||
@@ -1142,11 +1059,6 @@ int dev_is_rotational(struct dev_types *dt, struct device *dev)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dev_is_pmem(struct dev_types *dt, struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
@@ -1261,8 +1173,10 @@ int udev_dev_is_md_component(struct device *dev)
|
||||
const char *value;
|
||||
int ret = 0;
|
||||
|
||||
if (!obtain_device_list_from_udev())
|
||||
if (!obtain_device_list_from_udev()) {
|
||||
dev->flags |= DEV_UDEV_INFO_MISSING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(udev_device = _udev_get_dev(dev)))
|
||||
return 0;
|
||||
@@ -1289,6 +1203,7 @@ int udev_dev_is_mpath_component(struct device *dev)
|
||||
|
||||
int udev_dev_is_md_component(struct device *dev)
|
||||
{
|
||||
dev->flags |= DEV_UDEV_INFO_MISSING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -83,7 +83,6 @@ int dev_is_md_with_end_superblock(struct dev_types *dt, struct device *dev);
|
||||
int major_max_partitions(struct dev_types *dt, int major);
|
||||
int dev_is_partitioned(struct dev_types *dt, struct device *dev);
|
||||
int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result);
|
||||
int dev_get_partition_number(struct device *dev, int *num);
|
||||
|
||||
/* Various device properties */
|
||||
unsigned long dev_alignment_offset(struct dev_types *dt, struct device *dev);
|
||||
@@ -94,12 +93,8 @@ unsigned long dev_discard_granularity(struct dev_types *dt, struct device *dev);
|
||||
|
||||
int dev_is_rotational(struct dev_types *dt, struct device *dev);
|
||||
|
||||
int dev_is_pmem(struct dev_types *dt, struct device *dev);
|
||||
|
||||
int dev_is_nvme(struct dev_types *dt, struct device *dev);
|
||||
int dev_is_pmem(struct device *dev);
|
||||
|
||||
int dev_is_lv(struct device *dev);
|
||||
|
||||
int get_fs_block_size(struct device *dev, uint32_t *fs_block_size);
|
||||
|
||||
#endif
|
||||
|
@@ -37,8 +37,7 @@
|
||||
#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 */
|
||||
#define DEV_IS_NVME 0x00040000 /* set if dev is nvme */
|
||||
#define DEV_MATCHED_USE_ID 0x00080000 /* matched an entry from cmd->use_devices */
|
||||
#define DEV_UDEV_INFO_MISSING 0x00040000 /* we have no udev info for this device */
|
||||
|
||||
/*
|
||||
* Support for external device info.
|
||||
@@ -57,54 +56,12 @@ struct dev_ext {
|
||||
void *handle;
|
||||
};
|
||||
|
||||
#define DEV_ID_TYPE_SYS_WWID 0x0001
|
||||
#define DEV_ID_TYPE_SYS_SERIAL 0x0002
|
||||
#define DEV_ID_TYPE_MPATH_UUID 0x0003
|
||||
#define DEV_ID_TYPE_MD_UUID 0x0004
|
||||
#define DEV_ID_TYPE_LOOP_FILE 0x0005
|
||||
#define DEV_ID_TYPE_CRYPT_UUID 0x0006
|
||||
#define DEV_ID_TYPE_LVMLV_UUID 0x0007
|
||||
#define DEV_ID_TYPE_DEVNAME 0x0008
|
||||
|
||||
/*
|
||||
* A device ID of a certain type for a device.
|
||||
* A struct device may have multiple dev_id structs on dev->ids.
|
||||
* One of them will be the one that's used, pointed to by dev->id.
|
||||
*/
|
||||
|
||||
struct dev_id {
|
||||
struct dm_list list;
|
||||
struct device *dev;
|
||||
uint16_t idtype; /* DEV_ID_TYPE_ */
|
||||
char *idname; /* id string determined by idtype */
|
||||
};
|
||||
|
||||
/*
|
||||
* A device listed in devices file that lvm should use.
|
||||
* Each entry in the devices file is represented by a struct dev_use.
|
||||
* The structs are kept on cmd->use_devices.
|
||||
* idtype/idname/pvid/part are set when reading the devices file.
|
||||
* du->dev is set when a struct dev_use is matched to a struct device.
|
||||
*/
|
||||
|
||||
struct dev_use {
|
||||
struct dm_list list;
|
||||
struct device *dev;
|
||||
int part;
|
||||
uint16_t idtype;
|
||||
char *idname;
|
||||
char *devname;
|
||||
char *pvid;
|
||||
};
|
||||
|
||||
/*
|
||||
* All devices in LVM will be represented by one of these.
|
||||
* pointer comparisons are valid.
|
||||
*/
|
||||
struct device {
|
||||
struct dm_list aliases; /* struct dm_str_list */
|
||||
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;
|
||||
|
||||
/* private */
|
||||
@@ -114,10 +71,7 @@ struct device {
|
||||
int logical_block_size; /* From BLKSSZGET: lowest possible block size that the storage device can address */
|
||||
int read_ahead;
|
||||
int bcache_fd;
|
||||
int bcache_di;
|
||||
int part; /* partition number */
|
||||
uint32_t flags;
|
||||
uint32_t filtered_flags;
|
||||
unsigned size_seqno;
|
||||
uint64_t size;
|
||||
uint64_t end;
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2007 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 _LVM_DEVICE_ID_H
|
||||
#define _LVM_DEVICE_ID_H
|
||||
|
||||
void free_du(struct dev_use *du);
|
||||
void free_dus(struct dm_list *list);
|
||||
void free_did(struct dev_id *did);
|
||||
void free_dids(struct dm_list *list);
|
||||
const char *idtype_to_str(uint16_t idtype);
|
||||
uint16_t idtype_from_str(const char *str);
|
||||
const char *dev_idtype_for_metadata(struct cmd_context *cmd, struct device *dev);
|
||||
const char *dev_idname_for_metadata(struct cmd_context *cmd, struct device *dev);
|
||||
int device_ids_use_devname(struct cmd_context *cmd);
|
||||
int device_ids_read(struct cmd_context *cmd);
|
||||
int device_ids_write(struct cmd_context *cmd);
|
||||
int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid,
|
||||
const char *idtype_arg, const char *id_arg);
|
||||
void device_id_pvremove(struct cmd_context *cmd, struct device *dev);
|
||||
void device_ids_match(struct cmd_context *cmd);
|
||||
int device_ids_match_dev(struct cmd_context *cmd, struct device *dev);
|
||||
void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, int *device_ids_invalid, int noupdate);
|
||||
int device_ids_version_unchanged(struct cmd_context *cmd);
|
||||
void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_list, int *search_count, int noupdate);
|
||||
const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, uint16_t idtype);
|
||||
|
||||
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);
|
||||
|
||||
char *devices_file_version(void);
|
||||
int devices_file_exists(struct cmd_context *cmd);
|
||||
int devices_file_touch(struct cmd_context *cmd);
|
||||
int lock_devices_file(struct cmd_context *cmd, int mode);
|
||||
int lock_devices_file_try(struct cmd_context *cmd, int mode, int *held);
|
||||
void unlock_devices_file(struct cmd_context *cmd);
|
||||
|
||||
void devices_file_init(struct cmd_context *cmd);
|
||||
void devices_file_exit(struct cmd_context *cmd);
|
||||
|
||||
void unlink_searched_devnames(struct cmd_context *cmd);
|
||||
|
||||
#endif
|
@@ -399,19 +399,17 @@ int lvdisplay_full(struct cmd_context *cmd,
|
||||
void *handle __attribute__((unused)))
|
||||
{
|
||||
struct lvinfo info;
|
||||
int inkernel, snap_active = 0, partial = 0, raid_is_avail = 1;
|
||||
int inkernel, snap_active = 0;
|
||||
char uuid[64] __attribute__((aligned(8)));
|
||||
const char *access_str;
|
||||
struct lv_segment *snap_seg = NULL, *mirror_seg = NULL;
|
||||
struct lv_segment *seg = NULL;
|
||||
int lvm1compat;
|
||||
dm_percent_t snap_percent;
|
||||
int thin_pool_active = 0;
|
||||
dm_percent_t thin_data_percent = 0, thin_metadata_percent = 0;
|
||||
int thin_data_active = 0, thin_metadata_active = 0;
|
||||
dm_percent_t thin_data_percent, thin_metadata_percent;
|
||||
int thin_active = 0;
|
||||
dm_percent_t thin_percent = 0;
|
||||
struct lv_status_thin *thin_status = NULL;
|
||||
struct lv_status_thin_pool *thin_pool_status = NULL;
|
||||
dm_percent_t thin_percent;
|
||||
struct lv_status_cache *cache_status = NULL;
|
||||
struct lv_status_vdo *vdo_status = NULL;
|
||||
|
||||
@@ -475,7 +473,7 @@ int lvdisplay_full(struct cmd_context *cmd,
|
||||
snap_active ? "active" : "INACTIVE");
|
||||
}
|
||||
snap_seg = NULL;
|
||||
} else if (lv_is_cow(lv) && (snap_seg = find_snapshot(lv))) {
|
||||
} else if ((snap_seg = find_snapshot(lv))) {
|
||||
if (inkernel &&
|
||||
(snap_active = lv_snapshot_percent(snap_seg->cow,
|
||||
&snap_percent)))
|
||||
@@ -505,18 +503,15 @@ int lvdisplay_full(struct cmd_context *cmd,
|
||||
if (seg->merge_lv)
|
||||
log_print("LV merging to %s",
|
||||
seg->merge_lv->name);
|
||||
if (inkernel && (thin_active = lv_thin_status(lv, 0, &thin_status))) {
|
||||
thin_percent = thin_status->usage;
|
||||
dm_pool_destroy(thin_status->mem);
|
||||
}
|
||||
if (inkernel)
|
||||
thin_active = lv_thin_percent(lv, 0, &thin_percent);
|
||||
if (lv_is_merging_origin(lv))
|
||||
log_print("LV merged with %s",
|
||||
find_snapshot(lv)->lv->name);
|
||||
} else if (lv_is_thin_pool(lv)) {
|
||||
if ((thin_pool_active = lv_thin_pool_status(lv, 0, &thin_pool_status))) {
|
||||
thin_data_percent = thin_pool_status->data_usage;
|
||||
thin_metadata_percent = thin_pool_status->metadata_usage;
|
||||
dm_pool_destroy(thin_pool_status->mem);
|
||||
if (lv_info(cmd, lv, 1, &info, 1, 1) && info.exists) {
|
||||
thin_data_active = lv_thin_pool_percent(lv, 0, &thin_data_percent);
|
||||
thin_metadata_active = lv_thin_pool_percent(lv, 1, &thin_metadata_percent);
|
||||
}
|
||||
/* FIXME: display thin_pool targets transid for activated LV as well */
|
||||
seg = first_seg(lv);
|
||||
@@ -558,18 +553,11 @@ int lvdisplay_full(struct cmd_context *cmd,
|
||||
log_print("LV VDO Pool name %s", seg_lv(seg, 0)->name);
|
||||
}
|
||||
|
||||
if (lv_is_partial(lv))
|
||||
partial = 1;
|
||||
|
||||
if (lv_is_raid(lv))
|
||||
raid_is_avail = raid_is_available(lv) ? 1 : 0;
|
||||
|
||||
if (inkernel && info.suspended)
|
||||
log_print("LV Status suspended");
|
||||
else if (activation())
|
||||
log_print("LV Status %savailable%s",
|
||||
(inkernel && raid_is_avail) ? "" : "NOT ",
|
||||
partial ? " (partial)" : "");
|
||||
log_print("LV Status %savailable",
|
||||
inkernel ? "" : "NOT ");
|
||||
|
||||
/********* FIXME lv_number
|
||||
log_print("LV # %u", lv->lv_number + 1);
|
||||
@@ -603,12 +591,13 @@ int lvdisplay_full(struct cmd_context *cmd,
|
||||
dm_pool_destroy(cache_status->mem);
|
||||
}
|
||||
|
||||
if (thin_pool_active) {
|
||||
if (thin_data_active)
|
||||
log_print("Allocated pool data %s%%",
|
||||
display_percent(cmd, thin_data_percent));
|
||||
|
||||
if (thin_metadata_active)
|
||||
log_print("Allocated metadata %s%%",
|
||||
display_percent(cmd, thin_metadata_percent));
|
||||
}
|
||||
|
||||
if (thin_active)
|
||||
log_print("Mapped size %s%%",
|
||||
|
@@ -60,16 +60,13 @@ static void _composite_destroy(struct dev_filter *f)
|
||||
free(f);
|
||||
}
|
||||
|
||||
static void _wipe(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||
static void _wipe(struct dev_filter *f)
|
||||
{
|
||||
struct dev_filter **filters;
|
||||
|
||||
for (filters = (struct dev_filter **) f->private; *filters; ++filters) {
|
||||
if (use_filter_name && strcmp((*filters)->name, use_filter_name))
|
||||
continue;
|
||||
for (filters = (struct dev_filter **) f->private; *filters; ++filters)
|
||||
if ((*filters)->wipe)
|
||||
(*filters)->wipe(cmd, *filters, dev, use_filter_name);
|
||||
}
|
||||
(*filters)->wipe(*filters);
|
||||
}
|
||||
|
||||
struct dev_filter *composite_filter_create(int n, int use_dev_ext_info, struct dev_filter **filters)
|
||||
|
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU Lesser General Public License v.2.1.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 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"
|
||||
#include "lib/commands/toolcontext.h"
|
||||
|
||||
static int _passes_deviceid_filter(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||
{
|
||||
dev->filtered_flags &= ~DEV_FILTERED_DEVICES_FILE;
|
||||
dev->filtered_flags &= ~DEV_FILTERED_DEVICES_LIST;
|
||||
|
||||
if (!cmd->enable_devices_file && !cmd->enable_devices_list)
|
||||
return 1;
|
||||
|
||||
if (cmd->filter_deviceid_skip)
|
||||
return 1;
|
||||
|
||||
if (dev->flags & DEV_MATCHED_USE_ID)
|
||||
return 1;
|
||||
|
||||
if (cmd->enable_devices_file)
|
||||
dev->filtered_flags |= DEV_FILTERED_DEVICES_FILE;
|
||||
else if (cmd->enable_devices_list)
|
||||
dev->filtered_flags |= DEV_FILTERED_DEVICES_LIST;
|
||||
|
||||
log_debug_devs("%s: Skipping (deviceid)", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _destroy_deviceid_filter(struct dev_filter *f)
|
||||
{
|
||||
if (f->use_count)
|
||||
log_error(INTERNAL_ERROR "Destroying deviceid filter while in use %u times.", f->use_count);
|
||||
|
||||
free(f);
|
||||
}
|
||||
|
||||
struct dev_filter *deviceid_filter_create(struct cmd_context *cmd)
|
||||
{
|
||||
struct dev_filter *f;
|
||||
|
||||
if (!(f = zalloc(sizeof(struct dev_filter)))) {
|
||||
log_error("deviceid filter allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f->passes_filter = _passes_deviceid_filter;
|
||||
f->destroy = _destroy_deviceid_filter;
|
||||
f->use_count = 0;
|
||||
f->name = "deviceid";
|
||||
|
||||
log_debug_devs("deviceid filter initialised.");
|
||||
|
||||
return f;
|
||||
}
|
@@ -15,7 +15,6 @@
|
||||
#include "base/memory/zalloc.h"
|
||||
#include "lib/misc/lib.h"
|
||||
#include "lib/filters/filter.h"
|
||||
#include "lib/commands/toolcontext.h"
|
||||
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
#include <libudev.h>
|
||||
@@ -70,11 +69,6 @@ static int _ignore_fwraid(struct cmd_context *cmd, struct dev_filter *f __attrib
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (cmd->filter_nodata_only)
|
||||
return 1;
|
||||
|
||||
dev->filtered_flags &= ~DEV_FILTERED_FWRAID;
|
||||
|
||||
if (!fwraid_filtering())
|
||||
return 1;
|
||||
|
||||
@@ -86,14 +80,12 @@ static int _ignore_fwraid(struct cmd_context *cmd, struct dev_filter *f __attrib
|
||||
else
|
||||
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
|
||||
dev_ext_name(dev), dev->ext.handle);
|
||||
dev->filtered_flags |= DEV_FILTERED_FWRAID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
log_debug_devs("%s: Skipping: error in firmware RAID component detection",
|
||||
dev_name(dev));
|
||||
dev->filtered_flags |= DEV_FILTERED_FWRAID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -42,8 +42,6 @@ static int _passes_internal(struct cmd_context *cmd, struct dev_filter *f __attr
|
||||
{
|
||||
struct device_list *devl;
|
||||
|
||||
dev->filtered_flags &= ~DEV_FILTERED_INTERNAL;
|
||||
|
||||
if (!internal_filtering())
|
||||
return 1;
|
||||
|
||||
@@ -52,7 +50,6 @@ static int _passes_internal(struct cmd_context *cmd, struct dev_filter *f __attr
|
||||
return 1;
|
||||
}
|
||||
|
||||
dev->filtered_flags |= DEV_FILTERED_INTERNAL;
|
||||
log_debug_devs("%s: Skipping for internal filtering.", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
@@ -86,11 +86,6 @@ static int _passes_md_filter(struct cmd_context *cmd, struct dev_filter *f __att
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (cmd->filter_nodata_only)
|
||||
return 1;
|
||||
|
||||
dev->filtered_flags &= ~DEV_FILTERED_MD_COMPONENT;
|
||||
|
||||
/*
|
||||
* When md_component_dectection=0, don't even try to skip md
|
||||
* components.
|
||||
@@ -117,14 +112,12 @@ static int _passes_md_filter(struct cmd_context *cmd, struct dev_filter *f __att
|
||||
else
|
||||
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
|
||||
dev_ext_name(dev), dev->ext.handle);
|
||||
dev->filtered_flags |= DEV_FILTERED_MD_COMPONENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
log_debug_devs("%s: Skipping: error in md component detection",
|
||||
dev_name(dev));
|
||||
dev->filtered_flags |= DEV_FILTERED_MD_COMPONENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -16,7 +16,6 @@
|
||||
#include "lib/misc/lib.h"
|
||||
#include "lib/filters/filter.h"
|
||||
#include "lib/activate/activate.h"
|
||||
#include "lib/commands/toolcontext.h"
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
#include <libudev.h>
|
||||
#include "lib/device/dev-ext-udev-constants.h"
|
||||
@@ -28,6 +27,7 @@
|
||||
|
||||
#define MPATH_PREFIX "mpath-"
|
||||
|
||||
|
||||
struct mpath_priv {
|
||||
struct dm_pool *mem;
|
||||
struct dev_filter f;
|
||||
@@ -35,9 +35,6 @@ struct mpath_priv {
|
||||
struct dm_hash_table *hash;
|
||||
};
|
||||
|
||||
/*
|
||||
* given "/dev/foo" return "foo"
|
||||
*/
|
||||
static const char *_get_sysfs_name(struct device *dev)
|
||||
{
|
||||
const char *name;
|
||||
@@ -56,11 +53,6 @@ static const char *_get_sysfs_name(struct device *dev)
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* given major:minor
|
||||
* readlink translates /sys/dev/block/major:minor to /sys/.../foo
|
||||
* from /sys/.../foo return "foo"
|
||||
*/
|
||||
static const char *_get_sysfs_name_by_devt(const char *sysfs_dir, dev_t devno,
|
||||
char *buf, size_t buf_size)
|
||||
{
|
||||
@@ -68,7 +60,7 @@ static const char *_get_sysfs_name_by_devt(const char *sysfs_dir, dev_t devno,
|
||||
char path[PATH_MAX];
|
||||
int size;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d", sysfs_dir,
|
||||
if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d", sysfs_dir,
|
||||
(int) MAJOR(devno), (int) MINOR(devno)) < 0) {
|
||||
log_error("Sysfs path string is too long.");
|
||||
return NULL;
|
||||
@@ -110,28 +102,27 @@ static int _get_sysfs_string(const char *path, char *buffer, int max_size)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _get_sysfs_dm_mpath(struct dev_types *dt, const char *sysfs_dir, const char *holder_name)
|
||||
static int _get_sysfs_get_major_minor(const char *sysfs_dir, const char *kname, int *major, int *minor)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char buffer[128];
|
||||
char path[PATH_MAX], buffer[64];
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%sblock/%s/dm/uuid", sysfs_dir, holder_name) < 0) {
|
||||
if (dm_snprintf(path, sizeof(path), "%s/block/%s/dev", sysfs_dir, kname) < 0) {
|
||||
log_error("Sysfs path string is too long.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer[0] = '\0';
|
||||
|
||||
if (!_get_sysfs_string(path, buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
|
||||
if (!strncmp(buffer, MPATH_PREFIX, 6))
|
||||
return 1;
|
||||
if (sscanf(buffer, "%d:%d", major, minor) != 2) {
|
||||
log_error("Failed to parse major minor from %s", buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _get_holder_name(const char *dir, char *name, int max_size)
|
||||
static int _get_parent_mpath(const char *dir, char *name, int max_size)
|
||||
{
|
||||
struct dirent *d;
|
||||
DIR *dr;
|
||||
@@ -158,13 +149,13 @@ static int _get_holder_name(const char *dir, char *name, int max_size)
|
||||
}
|
||||
|
||||
if (closedir(dr))
|
||||
log_sys_debug("closedir", dir);
|
||||
log_sys_error("closedir", dir);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
static int _udev_dev_is_mpath_component(struct device *dev)
|
||||
static int _udev_dev_is_mpath(struct device *dev)
|
||||
{
|
||||
const char *value;
|
||||
struct dev_ext *ext;
|
||||
@@ -183,148 +174,95 @@ static int _udev_dev_is_mpath_component(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int _udev_dev_is_mpath_component(struct device *dev)
|
||||
static int _udev_dev_is_mpath(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _native_dev_is_mpath_component(struct cmd_context *cmd, struct dev_filter *f, struct device *dev)
|
||||
static int _native_dev_is_mpath(struct dev_filter *f, struct device *dev)
|
||||
{
|
||||
struct mpath_priv *mp = (struct mpath_priv *) f->private;
|
||||
struct dev_types *dt = mp->dt;
|
||||
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/" */
|
||||
char dm_dev_path[PATH_MAX]; /* e.g. "/dev/dm-1" */
|
||||
char holder_name[256]; /* e.g. "dm-1" */
|
||||
const char *sysfs_dir = dm_sysfs_dir();
|
||||
int dev_major = MAJOR(dev->dev);
|
||||
int dev_minor = MINOR(dev->dev);
|
||||
int dm_dev_major;
|
||||
int dm_dev_minor;
|
||||
const char *part_name, *name;
|
||||
struct stat info;
|
||||
char path[PATH_MAX], parent_name[PATH_MAX];
|
||||
const char *sysfs_dir = dm_sysfs_dir();
|
||||
int major = MAJOR(dev->dev);
|
||||
int minor = MINOR(dev->dev);
|
||||
dev_t primary_dev;
|
||||
long look;
|
||||
|
||||
/* Limit this filter to SCSI or NVME devices */
|
||||
if (!major_is_scsi_device(dt, dev_major) && !dev_is_nvme(dt, dev))
|
||||
/* Limit this filter only to SCSI devices */
|
||||
if (!major_is_scsi_device(dt, MAJOR(dev->dev)))
|
||||
return 0;
|
||||
|
||||
switch (dev_get_primary_dev(dt, dev, &primary_dev)) {
|
||||
|
||||
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))))
|
||||
if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, parent_name, sizeof(parent_name))))
|
||||
return_0;
|
||||
|
||||
log_debug_devs("%s: Device is a partition, using primary "
|
||||
"device %s for mpath component detection",
|
||||
part_name, name);
|
||||
break;
|
||||
|
||||
case 1: /* The dev is already a primary dev. Just continue with the dev. */
|
||||
|
||||
/* gets "foo" for "/dev/foo" */
|
||||
if (!(name = _get_sysfs_name(dev)))
|
||||
return_0;
|
||||
break;
|
||||
|
||||
default: /* 0, error. */
|
||||
log_warn("Failed to get primary device for %d:%d.", dev_major, dev_minor);
|
||||
log_warn("Failed to get primary device for %d:%d.", major, minor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dm_snprintf(holders_path, sizeof(holders_path), "%sblock/%s/holders", sysfs_dir, name) < 0) {
|
||||
if (dm_snprintf(path, sizeof(path), "%s/block/%s/holders", sysfs_dir, name) < 0) {
|
||||
log_warn("Sysfs path to check mpath is too long.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* also will filter out partitions */
|
||||
if (stat(holders_path, &info))
|
||||
if (stat(path, &info))
|
||||
return 0;
|
||||
|
||||
if (!S_ISDIR(info.st_mode)) {
|
||||
log_warn("Path %s is not a directory.", holders_path);
|
||||
log_warn("Path %s is not a directory.", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If holders dir contains an entry such as "dm-1", then this sets
|
||||
* holder_name to "dm-1".
|
||||
*
|
||||
* If holders dir is empty, return 0 (this is generally where
|
||||
* devs that are not mpath components return.)
|
||||
*/
|
||||
if (!_get_holder_name(holders_path, holder_name, sizeof(holder_name)))
|
||||
if (!_get_parent_mpath(path, parent_name, sizeof(parent_name)))
|
||||
return 0;
|
||||
|
||||
if (dm_snprintf(dm_dev_path, sizeof(dm_dev_path), "%s/%s", cmd->dev_dir, holder_name) < 0) {
|
||||
log_warn("dm device path to check mpath is too long.");
|
||||
return 0;
|
||||
}
|
||||
if (!_get_sysfs_get_major_minor(sysfs_dir, parent_name, &major, &minor))
|
||||
return_0;
|
||||
|
||||
/*
|
||||
* stat "/dev/dm-1" which is the holder of the dev we're checking
|
||||
* dm_dev_major:dm_dev_minor come from stat("/dev/dm-1")
|
||||
*/
|
||||
if (stat(dm_dev_path, &info)) {
|
||||
log_debug("filter-mpath %s holder %s stat result %d",
|
||||
dev_name(dev), dm_dev_path, errno);
|
||||
if (major != dt->device_mapper_major)
|
||||
return 0;
|
||||
}
|
||||
dm_dev_major = (int)MAJOR(info.st_rdev);
|
||||
dm_dev_minor = (int)MINOR(info.st_rdev);
|
||||
|
||||
if (dm_dev_major != dt->device_mapper_major) {
|
||||
log_debug_devs("filter-mpath %s holder %s %d:%d does not have dm major",
|
||||
dev_name(dev), dm_dev_path, dm_dev_major, dm_dev_minor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the result of checking that "/dev/dm-1" is an mpath device
|
||||
* to avoid repeating it for each path component.
|
||||
* The minor number of "/dev/dm-1" is added to the hash table with
|
||||
* const value 2 meaning that dm minor 1 (for /dev/dm-1) is a multipath dev
|
||||
* and const value 1 meaning that dm minor 1 is not a multipath dev.
|
||||
*/
|
||||
look = (long) dm_hash_lookup_binary(mp->hash, &dm_dev_minor, sizeof(dm_dev_minor));
|
||||
/* Avoid repeated detection of multipath device and use first checked result */
|
||||
look = (long) dm_hash_lookup_binary(mp->hash, &minor, sizeof(minor));
|
||||
if (look > 0) {
|
||||
log_debug_devs("filter-mpath %s holder %s %u:%u already checked as %sbeing mpath.",
|
||||
dev_name(dev), holder_name, dm_dev_major, dm_dev_minor, (look > 1) ? "" : "not ");
|
||||
log_debug_devs("%s(%u:%u): already checked as %sbeing mpath.",
|
||||
parent_name, major, minor, (look > 1) ? "" : "not ");
|
||||
return (look > 1) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if /sys/block/<holder_name>/dm/uuid indicates that
|
||||
* <holder_name> is a dm device with dm uuid prefix mpath-.
|
||||
* When true, <holder_name> will be something like "dm-1".
|
||||
*
|
||||
* (Is a hash table worth it to avoid reading one sysfs file?)
|
||||
*/
|
||||
if (_get_sysfs_dm_mpath(dt, sysfs_dir, holder_name)) {
|
||||
log_debug_devs("filter-mpath %s holder %s %u:%u ignore mpath component",
|
||||
dev_name(dev), holder_name, dm_dev_major, dm_dev_minor);
|
||||
(void) dm_hash_insert_binary(mp->hash, &dm_dev_minor, sizeof(dm_dev_minor), (void*)2);
|
||||
if (lvm_dm_prefix_check(major, minor, MPATH_PREFIX)) {
|
||||
(void) dm_hash_insert_binary(mp->hash, &minor, sizeof(minor), (void*)2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
(void) dm_hash_insert_binary(mp->hash, &dm_dev_minor, sizeof(dm_dev_minor), (void*)1);
|
||||
(void) dm_hash_insert_binary(mp->hash, &minor, sizeof(minor), (void*)1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dev_is_mpath_component(struct cmd_context *cmd, struct dev_filter *f, struct device *dev)
|
||||
static int _dev_is_mpath(struct dev_filter *f, struct device *dev)
|
||||
{
|
||||
if (dev->ext.src == DEV_EXT_NONE)
|
||||
return _native_dev_is_mpath_component(cmd, f, dev);
|
||||
return _native_dev_is_mpath(f, dev);
|
||||
|
||||
if (dev->ext.src == DEV_EXT_UDEV)
|
||||
return _udev_dev_is_mpath_component(dev);
|
||||
return _udev_dev_is_mpath(dev);
|
||||
|
||||
log_error(INTERNAL_ERROR "Missing hook for mpath recognition "
|
||||
"using external device info source %s", dev_ext_name(dev));
|
||||
@@ -334,17 +272,14 @@ static int _dev_is_mpath_component(struct cmd_context *cmd, struct dev_filter *f
|
||||
|
||||
#define MSG_SKIPPING "%s: Skipping mpath component device"
|
||||
|
||||
static int _ignore_mpath_component(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||
static int _ignore_mpath(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||
{
|
||||
dev->filtered_flags &= ~DEV_FILTERED_MPATH_COMPONENT;
|
||||
|
||||
if (_dev_is_mpath_component(cmd, f, dev) == 1) {
|
||||
if (_dev_is_mpath(f, dev) == 1) {
|
||||
if (dev->ext.src == DEV_EXT_NONE)
|
||||
log_debug_devs(MSG_SKIPPING, dev_name(dev));
|
||||
else
|
||||
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
|
||||
dev_ext_name(dev), dev->ext.handle);
|
||||
dev->filtered_flags |= DEV_FILTERED_MPATH_COMPONENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -365,8 +300,8 @@ static void _destroy(struct dev_filter *f)
|
||||
struct dev_filter *mpath_filter_create(struct dev_types *dt)
|
||||
{
|
||||
const char *sysfs_dir = dm_sysfs_dir();
|
||||
struct mpath_priv *mp;
|
||||
struct dm_pool *mem;
|
||||
struct mpath_priv *mp;
|
||||
struct dm_hash_table *hash;
|
||||
|
||||
if (!*sysfs_dir) {
|
||||
@@ -374,7 +309,7 @@ struct dev_filter *mpath_filter_create(struct dev_types *dt)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(hash = dm_hash_create(110))) {
|
||||
if (!(hash = dm_hash_create(128))) {
|
||||
log_error("mpath hash table creation failed.");
|
||||
return NULL;
|
||||
}
|
||||
@@ -390,13 +325,19 @@ struct dev_filter *mpath_filter_create(struct dev_types *dt)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
mp->f.passes_filter = _ignore_mpath_component;
|
||||
if (!(mp = dm_pool_zalloc(mem, sizeof(*mp)))) {
|
||||
log_error("mpath filter allocation failed.");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
mp->f.passes_filter = _ignore_mpath;
|
||||
mp->f.destroy = _destroy;
|
||||
mp->f.use_count = 0;
|
||||
mp->f.private = mp;
|
||||
mp->f.name = "mpath";
|
||||
mp->dt = dt;
|
||||
|
||||
mp->mem = mem;
|
||||
mp->dt = dt;
|
||||
mp->hash = hash;
|
||||
|
||||
log_debug_devs("mpath filter initialised.");
|
||||
|
@@ -16,7 +16,6 @@
|
||||
#include "base/memory/zalloc.h"
|
||||
#include "lib/misc/lib.h"
|
||||
#include "lib/filters/filter.h"
|
||||
#include "lib/commands/toolcontext.h"
|
||||
|
||||
#define MSG_SKIPPING "%s: Skipping: Partition table signature found"
|
||||
|
||||
@@ -25,11 +24,6 @@ static int _passes_partitioned_filter(struct cmd_context *cmd, struct dev_filter
|
||||
struct dev_types *dt = (struct dev_types *) f->private;
|
||||
int ret;
|
||||
|
||||
if (cmd->filter_nodata_only)
|
||||
return 1;
|
||||
|
||||
dev->filtered_flags &= ~DEV_FILTERED_PARTITIONED;
|
||||
|
||||
ret = dev_is_partitioned(dt, dev);
|
||||
|
||||
if (ret == -EAGAIN) {
|
||||
@@ -45,7 +39,6 @@ static int _passes_partitioned_filter(struct cmd_context *cmd, struct dev_filter
|
||||
else
|
||||
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
|
||||
dev_ext_name(dev), dev->ext.handle);
|
||||
dev->filtered_flags |= DEV_FILTERED_PARTITIONED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -58,23 +58,17 @@ static int _init_hash(struct pfilter *pf)
|
||||
if (pf->devices)
|
||||
dm_hash_destroy(pf->devices);
|
||||
|
||||
if (!(pf->devices = dm_hash_create(111)))
|
||||
if (!(pf->devices = dm_hash_create(128)))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _persistent_filter_wipe(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||
static void _persistent_filter_wipe(struct dev_filter *f)
|
||||
{
|
||||
struct pfilter *pf = (struct pfilter *) f->private;
|
||||
struct dm_str_list *sl;
|
||||
|
||||
if (!dev) {
|
||||
dm_hash_wipe(pf->devices);
|
||||
} else {
|
||||
dm_list_iterate_items(sl, &dev->aliases)
|
||||
dm_hash_remove(pf->devices, sl->str);
|
||||
}
|
||||
dm_hash_wipe(pf->devices);
|
||||
}
|
||||
|
||||
static int _lookup_p(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user